【问题标题】:Are all the std::tuple constructors necessary?所有的 std::tuple 构造函数都是必需的吗?
【发布时间】:2013-08-20 11:23:45
【问题描述】:

std::tuple 包含以下构造函数:

explicit tuple( const Types&... args );

template< class... UTypes >
explicit tuple( UTypes&&... args );

两者都有相同的描述,因为它们用args 中的对应值初始化每个元素。唯一的区别是第二个参数是转发的。

根据我对右值引用的理解,我不明白为什么需要第一个版本,因为可以将相同的参数传递到第二个版本。引用将被转发,没有人会更明智,尤其是因为没有提到移动语义。

谁能解释一下是什么让这两个构造函数都必需?

【问题讨论】:

  • 如果不是所有 UTypes 都可以隐式转换为相应的 Types,则第二个版本是 SFINAE-d 超出重载集

标签: c++ c++11 rvalue-reference stdtuple


【解决方案1】:

这是一个简化的例子:

template <typename T>
struct foo
{
    foo(const T&);
    template <typename U>
    foo(U&&);
};

第二个构造函数需要某种模板类型推导。这并不适用于所有情况,例如带有初始化列表。只有在第一个构造函数可用时,以下初始化才有效:

auto f = foo<std::vector<int>>{ { 1, 2, 3 } };

【讨论】:

    【解决方案2】:

    这用于 RValue 引用转发,并针对移动构造进行了优化。第一个版本用于左值。请参阅以下链接以更好地解释。

    http://thbecker.net/articles/rvalue_references/section_07.html

    【讨论】:

    • 第二个版本可用于右值引用和左值引用。
    • 同意,但编译器会在编译时为函数签名做出最佳选择,在这种情况下,他们提供了 2 个签名。我同意您的回答,并且它有助于模板扣除,因此是必需的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    • 2011-11-03
    • 1970-01-01
    相关资源
    最近更新 更多