为什么std::get
的{{1}}有这么多的重载(http://en.cppreference.com/w/cpp/utility/tuple/get)?一个对应std::tuple
const
和&
的每种可能组合?对于每个组合,返回值上的const ref限定符是相同的。为什么不通过转发引用只有一个单一的重载接受元组类型,然后根据输入的签名简单地转发返回值?像这样的东西
&&
这种事情会让人们很容易推断template <int Index, typename TupleType>
decltype(auto) get(TupleType&& tup);
函数的作用,并避免像问题2485(https://wg21.cmeerw.net/lwg/issue2485)
答案 0 :(得分:4)
std::get
存在于decltype(auto)
之前。这很容易。
好的,为什么不改变它?
std::get
的主体未由标准指定,并且不应该因为不同的编译器具有不同的元组布局和实现。
decltype(auto)
没有告诉读者标准,编译器的用户或实现者,返回类型是什么。它只是说它是从身体推断出来的。标准没有指定。
它在标准中就像那样没用,除非他们分别描述了返回值是什么,最终看起来很像列出重载。
答案 1 :(得分:2)
无法推断出std::get
的参数,因为std::get
是针对许多不同类型定义的。 (例如tuple
,pair
,array
,variant
)。
因此,任何其他std::get
都不能推断出其参数类型。此时将其更改为演绎会破坏现实世界的代码,例如从元组推导出的类型。例如,建议的签名更改将产生如下签名:
template <class TupleLike, class = enable_if_t<IsStdTuple<TupleLike>::value>>>
decltype(auto) get(TupleLike&&);
此签名不允许对接口中的元组类型进行隐式转换,就像旧签名一样。如上所述,这会将从std::tuple
派生的类型或具有转化运算符的类型分解为std::tuple
。
Libc ++使用单个通用tuple
重载实现pair
,array
和TupleLike
转换构造函数。作为维护者,我非常熟悉这些实现问题,如果我能按照你的建议实现一致的std::get
,我已经这样了。