问题标签 [perfect-forwarding]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 无法向包装函数添加完美转发
c++ - C++11 std::forward_as_tuple 和 std::forward
当我std::forward
将函数参数用作参数时,我应该使用它们std::forward_as_tuple
吗?
我知道它们将被存储为右值引用,但还有什么我应该考虑的吗?
c++ - 编译器如何知道必须调用 std::forward 函数的哪个重载?
以下签名被声明为std::forward
重载:
现在,考虑以下模板函数:
如果我写:
然后这就是编译器实例化foo_as_always
的方式T = int&
:
如果我写:
然后编译器实例foo_as_always
化T = int
:
在这两种情况下,t
变量在任何表达式中都是左值。编译器如何知道std::forward
必须调用函数的哪个重载?
c++ - 将可变参数模板参数传递给可变参数函数
我们正在使用第三方 C 库,它提供了printf()
-style 日志功能,
由于不值得讨论的原因,我们需要限制记录消息的速率,类似于
幸运的是,C 库的作者知道他们在做什么,并提供了
所以写上面的函数是一件比较简单的事情。不幸的是,可变参数函数不能很好地使用 inlining,所以我想出了第二个解决方案:
这完美地工作并根据我们的需要内联速率限制条件。但我有几个问题:
将参数包扩展为像这样的 C 风格的可变参数函数调用在 C++11 中是合法的、定义明确的事情,还是我们很幸运它可以工作?
鉴于我们正在调用 C 函数,这里是否真的有
&&
必要?如果我使用,甚至只是按价值,无论有没有 ,std::forward
它似乎都可以正常工作。const T&
T
std::forward
c++ - 通用引用和本地类
在下面的代码中,我有一个接受“通用引用”(F&&
)的函数。该函数还有一个内部类,它F&&
在其构造函数中接受一个对象。F&&
那时仍然是通用参考吗?ieF
仍然被认为是推导类型?
换句话说,我应该在构造函数初始化列表中使用std::forward<F>
还是?std::move
c++ - 创建 `std::forward` 别名 - 意外结果
我创建了一个std::forward
别名,其行为应与std::forward
.
然后我在我的代码库中替换了所有出现的std::forward<...>
with fwd<...>
。
编译了所有项目g++ 4.9
- 所有测试都通过了,一切正常。
然后我尝试用clang++ 3.5
. 一些测试似乎随机失败,原因是fwd<...>
. 将其替换为std::forward<...>
再次修复了失败的测试。
我尝试fwd<...>
使用尾随返回类型语法编写,因为我认为decltype(auto)
它不起作用:
相同的结果:g++
有效,clang++
无效。
然后我查找了std::forward
cppreference 的签名,并像这样实现了我的别名:
g++
这在和上都有效(所有测试都通过)clang++
。
为什么decltype(auto)
版本不工作?它不应该返回与 完全相同的返回类型std::forward
吗?
c++ - 了解完美转发和可变参数模板的片段
我已经从这个答案中看到了这段代码的片段,我似乎无法理解模板和类型名的排列如何创建 main() 中显示的最终函数调用。
特别是,可变参数模板模板的排列和 std::forward 的使用让我感到困惑。
任何人都可以分解这段代码以便我更好地理解它吗?
任何帮助将不胜感激。
c++ - 如何正确“完美向前”getter 函数?
我正在为 C++14 创建一个 JSON 库,并且尽可能使用移动语义。
我的Value
班级有几个 setter 和 getter,它们总是尽可能地尝试移动:
从代码中可以看出,使用模板和通用引用非常容易实现完美的转发 setter 函数。
我怎样才能对 getter 函数做同样的事情?我很确定我必须使用模板返回类型,但我不确定如何复制 ref-qualifiers 和 const-correctness。
c++ - 完美转发设置器的正确“enable_if”约束是什么?
Herb Sutter回归本源!CppCon上的现代 C++演示要点讨论了传递参数的不同选项,并比较了它们的性能与编写/教学的容易程度。“高级”选项(在所有测试案例中提供最佳性能,但对于大多数开发人员来说太难编写)是完美的转发,给出的示例(PDF,第 28 页):
该示例使用带有转发引用的模板函数,模板参数String
使用enable_if
. 然而,约束似乎是不正确的:似乎是说只有当String
类型不是 a时才可以使用这种方法std::string
,这是没有意义的。这意味着std::string
可以使用除值之外的任何内容来设置此成员std::string
。
我考虑的一种解释是,有一个简单的错字,并且该约束旨在std::is_same<std::decay_t<String>, std::string>::value
代替!std::is_same<std::decay_t<String>, std::string>::value
. 但是,这意味着 setter 不能用于例如,const char *
并且鉴于这是演示文稿中测试的案例之一,它显然打算与这种类型一起使用。
在我看来,正确的约束更像是:
允许任何可以分配给成员的内容与 setter 一起使用。
我有正确的约束吗?还有其他可以改进的地方吗?对原始约束是否有任何解释,也许是断章取义?
另外我想知道这个声明中复杂的、“不可教的”部分是否真的那么有益。由于我们没有使用重载,我们可以简单地依赖正常的模板实例化:
当然还有一些关于是否noexcept
真的重要的争论,有些人说除了移动/交换原语之外不要太担心它:
也许对于概念来说,约束模板不会太难,只是为了改进错误消息。
这仍然有缺点,它不能是虚拟的,并且它必须在标题中(尽管希望模块最终会渲染那个没有实际意义的),但这似乎相当可教。
c++ - 复制最少的正向函子
我想转发仿函数调用并仅在绝对必要时复制该仿函数。这是我的通用包装函数和仿函数:
我可以用
- 右值引用:包装器(Functor());
- 左值参考:函子 f;包装器(f);
- const 左值参考:const Functor f; 包装器(f);
- const 右值参考:const Functor make_functor(); 包装器(make_functor());
我只想在传递 const 引用时复制包装器的 arg。所以我来了这样的包装器实现:
不是很好并且错过了(不是很典型)const-rvalue-reference 案例,但基本上可以完成它的工作。
但我也可能有带有 const operator() 的 Functor
在那种情况下,我根本不需要复制包装器的 arg。
问题是:如果Functor有 const 括号运算符,我如何检查包装器?另一个问题是包装器是否可以在没有大量类型特征 typedef 行的情况下以更智能和更紧凑的方式实现?(实际上我担心的不是代码大小,而是代码的可读性)。