问题标签 [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 回答
577 浏览

c++ - G++ 4.5.0 中的 std::forward_as_tuple

我对该功能有迫切的需求std::forward_as_tuple,但仅限于使用 GCC 4.5.0(我知道这是一个糟糕的情况,但它会为我解决很多问题,所以请保持尖刻的言论最低限度)。标<tuple>头似乎不包含该功能(应该如此),所以我的问题是:

  1. 它是否隐藏在其他标题中?(这种情况以前发生过,但很难确定。)
  2. 是否可以推出自己的实现?那就是:它是否可以用在 GCC 4.5.0中实现的 c++11 的部分来实现?如果有人真的知道如何做到这一点,那么奖金。
0 投票
1 回答
5600 浏览

c++ - C++11 中的所有/大多数 setter 函数是否应该编写为接受通用引用的函数模板?

考虑一个X具有N成员变量的类,每个变量都有一些可复制可移动的类型,以及N相应的 setter 函数。在 C++98 中, 的定义X可能如下所示:

上述类的 Setter 函数X可以绑定到左值和右值参数。根据实际参数,这可能会导致创建临时文件并最终导致复制分配;因此,此设计不支持不可复制的类型。

在 C++11 中,我们拥有移动语义、完美转发和通用引用(Scott Meyers 的术语),通过以下方式重写 setter 函数,可以更高效、更通用地使用它们:

通用引用可以绑定到const/non- constvolatile/non-volatile和任何一般的可转换类型,避免创建临时变量并将值直接传递给operator =. 现在支持不可复制可移动的类型。可以通过static_assert或 通过消除可能不需要的绑定std::enable_if

所以我的问题是:作为设计指南,C++11 中的所有(比如说,大多数)setter 函数都应该写成接受通用引用的函数模板吗?

除了更繁琐的语法和在那些 setter 函数中编写代码时无法使用类似 Intellisense 的帮助工具之外,假设原则“将 setter 函数编写为函数模板,尽可能接受通用引用”是否有任何相关的缺点?

0 投票
1 回答
819 浏览

c++ - 具有完美转发的可变参数模板未针对移动语义进行优化

大家好,我在创建的可变参数添加模板上没有调用 move ctor 的问题。

0 投票
1 回答
3966 浏览

c++ - 可变模板参数的完美转发

我为通用信号/插槽系统编写了以下实现:

之后,我使用以下简单案例测试了我的课程:

案例 1 编译没有问题。另一方面,案例 2 在 GCC 4.7.2 下会产生以下错误:

我知道这个问题与完美转发有关(以及我对后者的误解)。但是,我从 std::make_shared() 和 std::make_tuple() 实现中得到了启发,我看不到将可变参数转发给代表的方式有什么不同。唯一显着的区别是 make_shared() 和 make_tuple() 都是函数模板,而不是类模板,例如上面的 Signal 实现。

- 编辑 -

作为对各种评论的回应,这里是一个新版本的 Signal 类实现,它不会受到上述问题的影响。此外,现在可以使用连接函数返回的不透明令牌断开委托。结果可能不像其他实现(例如 boost::signal)那样灵活和强大,但至少它具有简单和轻量级的优点。

0 投票
1 回答
202 浏览

c++ - 纯转发的习惯用法

混合这个问题另一个问题,我已经到了下一个(确实非常简单)的解决方案:想法是只在实际函数的范围内提供类型别名并在适当的点检查模板条件:

使用此代码,我们可以以舒适的方式添加一些我们想要的别名或条件。这段代码:

变为(仅some_fun):

firewall正如@ipc在我上面提出的第二个问题中所示,的目的是吸收任何可以重新替换定义为默认模板参数的本地类型别名的参数。

这也为避免其他更深层次的问题提供了一种有用的方法:当您只想使函数参数化以对预先已知的类型进行完美转发时;例如,在下一种情况下:

如果您想_str使用完美的转发机制进行初始化,则不可避免地会与任何其他模板参数产生歧义。使用以下附加宏可以轻松避免这种情况:

如果fwStr不是 type std::string,或者它们的常量版本std::string&std::string&&则会选择其他构造函数,如果没有其他构造函数,则会抛出编译器错误,std::enable_if<false, void>::type说不存在。

问题:在 C++ 中总是最好避免使用宏,但是众所周知的模板是冗长的,这些情况(特别是第二种情况)很常见,或者至少在我的经验中是这样。然后,这些宏非常有用。

在这种情况下使用宏是否危险?这通常是好还是有用的idiom,或者看起来什么都没有?

0 投票
2 回答
1747 浏览

c++ - 您是否曾经将 C++ RValue 引用参数标记为 const

我一直在切换模板工厂函数以使用(并理解)std::forward 来支持右值和移动语义。我通常用于模板类的样板工厂函数总是将参数标记为 const:

按预期编译。最初我将 MakeMyPair 转换为也将参数作为 const 传递,但这不会在我的 Mac 上使用 XCode 4.6 编译:

没有匹配函数调用“MakeMyPair_Forward”候选函数 [with T = int, U = bool] 不可行:第一个参数没有从“int”到“const int &&”的已知转换

这从http://en.cppreference.com/w/cpp/utility/forward是有道理的,其中状态 const 是推导出来的,我正在传递左值。

  • 如果对 wrapper() 的调用传递了一个右值 std::string,则 T 被推导出为 std::string(不是 std::string&、const std::string& 或 std::string&&),并且 std::forward 确保将右值引用传递给 foo。
  • 如果对 wrapper() 的调用传递了一个 const 左值 std::string,则将 T 推导出为 const std::string&,而 std::forward 确保将一个 const 左值引用传递给 foo。
  • 如果对 wrapper() 的调用传递了一个非常量左值 std::string,则 T 被推导出为 std::string&,并且 std::forward 确保将非常量左值引用传递给 foo。

使用右值和左值删除 const 可以按我的意愿工作。只有将右值作为类型传递才能与 MakeMyPair_Forward 参数上的 const 一起使用。

所以,问题。作为参数传递时将右值引用标记为 const 是否有意义?这不像我可以更改右值,这只是暂时的。在完成和修复我的代码之后,我对它使用 const 编译感到有点惊讶。为什么要将右值参数标记为 const?重点是只提供一个接受右值的 API 吗?如果是这样,您不会使用类型特征来防止左值引用吗?https://stackoverflow.com/a/7863645/620304

谢谢。

0 投票
2 回答
1288 浏览

c++ - 如何存储通用引用

我需要将通用引用存储在一个类中(我确信引用的值会比这个类更长寿)。有这样做的规范方法吗?

这是我想出的一个最小示例。它似乎有效,但我不确定我是否做对了。

我的推理是正确的还是会导致细微的错误?此外,是否有更好(即更简洁)的方式来编写构造函数?binder(F&& f, X&& x)将不起作用,因为这些是 r 值引用,因此不允许binder(f, i).

0 投票
1 回答
91 浏览

c++ - 完美的转发不接机方式

我收到以下代码的 SFINAE 错误,因为它不会使用模板。结果,我正在尝试完善 args 。任何想法任何人。

布莱尔

0 投票
1 回答
398 浏览

c++ - 如何将完美转发与大括号括起来的初始化程序结合起来

此代码编译:

以及该:

但是这个没有:

原因是第三个调用tuple(const Types&...),但这似乎是一个任意限制。

C++11 是否无法用可变参数模板表达这一点,还是有可能?

0 投票
1 回答
481 浏览

c++ - 为什么在右值的情况下转发引用不会推断为右值引用?

我知道,给定一个初始化转发/通用引用的表达式,左值被推断为类型T&和右值类型T(而不是T&&)。

因此,为了只允许右值,需要写

并不是,

我的问题是,为什么对于转发引用,右值被推断为类型T而不是T&&?我想,如果它们被推断为,T&&那么相同的引用折叠规则也T&& &&T&&.