问题标签 [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.

0 投票
2 回答
490 浏览

c++ - 无法向包装函数添加完美转发

在回答这个问题时,我编写了这个工作代码,包装函数传入模板参数:

示例用法(我使用此代码进行测试):

两个人告诉我使用完美转发。当我问如何做到这一点时,其中一位将我重定向到这里。我阅读问题,仔细阅读最佳答案,并更改wrapper为:

它会编译,除非我尝试使用上面的示例代码检查它。如何修复代码?

http://rextester.com/YUIYI99787

0 投票
3 回答
8327 浏览

c++ - C++11 std::forward_as_tuple 和 std::forward

当我std::forward将函数参数用作参数时,我应该使用它们std::forward_as_tuple吗?

我知道它们将被存储为右值引用,但还有什么我应该考虑的吗?

0 投票
1 回答
197 浏览

c++ - 编译器如何知道必须调用 std::forward 函数的哪个重载?

以下签名被声明为std::forward重载:

现在,考虑以下模板函数:

如果我写:

然后这就是编译器实例化foo_as_always的方式T = int&

如果我写:

然后编译器实例foo_as_alwaysT = int

在这两种情况下,t变量在任何表达式中都是左值。编译器如何知道std::forward必须调用函数的哪个重载?

0 投票
2 回答
3768 浏览

c++ - 将可变参数模板参数传递给可变参数函数

我们正在使用第三方 C 库,它提供了printf()-style 日志功能,

由于不值得讨论的原因,我们需要限制记录消息的速率,类似于

幸运的是,C 库的作者知道他们在做什么,并提供了

所以写上面的函数是一件比较简单的事情。不幸的是,可变参数函数不能很好地使用 inlining,所以我想出了第二个解决方案:

这完美地工作并根据我们的需要内联速率限制条件。但我有几个问题:

  • 将参数包扩展为像这样的 C 风格的可变参数函数调用在 C++11 中是合法的、定义明确的事情,还是我们很幸运它可以工作?

  • 鉴于我们正在调用 C 函数,这里是否真的有&&必要?如果我使用,甚至只是按价值,无论有没有 ,std::forward它似乎都可以正常工作。const T&Tstd::forward

0 投票
2 回答
214 浏览

c++ - 通用引用和本地类

在下面的代码中,我有一个接受“通用引用”(F&&)的函数。该函数还有一个内部类,它F&&在其构造函数中接受一个对象。F&&那时仍然是通用参考吗?ieF仍然被认为是推导类型?

换句话说,我应该在构造函数初始化列表中使用std::forward<F>还是?std::move

现场演示。

0 投票
1 回答
210 浏览

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::forwardcppreference 的签名,并像这样实现了我的别名:

g++这在和上都有效(所有测试都通过)clang++

为什么decltype(auto)版本不工作?它不应该返回与 完全相同的返回类型std::forward吗?

0 投票
2 回答
321 浏览

c++ - 了解完美转发和可变参数模板的片段

我已经从这个答案中看到了这段代码的片段,我似乎无法理解模板和类型名的排列如何创建 main() 中显示的最终函数调用。

特别是,可变参数模板模板的排列和 std::forward 的使用让我感到困惑。

任何人都可以分解这段代码以便我更好地理解它吗?

任何帮助将不胜感激。

0 投票
2 回答
982 浏览

c++ - 如何正确“完美向前”getter 函数?

我正在为 C++14 创建一个 JSON 库,并且尽可能使用移动语义。

我的Value班级有几个 setter 和 getter,它们总是尽可能地尝试移动:

从代码中可以看出,使用模板和通用引用非常容易实现完美的转发 setter 函数。

我怎样才能对 getter 函数做同样的事情?我很确定我必须使用模板返回类型,但我不确定如何复制 ref-qualifiers 和 const-correctness。

0 投票
3 回答
1647 浏览

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真的重要的争论,有些人说除了移动/交换原语之外不要太担心它:

也许对于概念来说,约束模板不会太难,只是为了改进错误消息。

这仍然有缺点,它不能是虚拟的,并且它必须在标题中(尽管希望模块最终会渲染那个没有实际意义的),但这似乎相当可教。

0 投票
1 回答
348 浏览

c++ - 复制最少的正向函子

我想转发仿函数调用并仅在绝对必要时复制该仿函数。这是我的通用包装函数和仿函数:

我可以用

  1. 右值引用:包装器(Functor());
  2. 左值参考:函子 f;包装器(f);
  3. const 左值参考:const Functor f; 包装器(f);
  4. const 右值参考:const Functor make_functor(); 包装器(make_functor());

我只想在传递 const 引用时复制包装器的 arg。所以我来了这样的包装器实现:

不是很好并且错过了(不是很典型)const-rvalue-reference 案例,但基本上可以完成它的工作。

但我也可能有带有 const operator() 的 Functor

在那种情况下,我根本不需要复制包装器的 arg。

问题是:如果Functor有 const 括号运算符,我如何检查包装器?另一个问题是包装器是否可以在没有大量类型特征 typedef 行的情况下以更智能和更紧凑的方式实现?(实际上我担心的不是代码大小,而是代码的可读性)。