#include <tuple>
int main() {
static_assert(std::is_same<std::tuple<int&&>,
decltype(std::forward_as_tuple(1))>::value, "");
constexpr int x = 5;
constexpr auto t1 = std::forward_as_tuple(1); // (1)
constexpr auto t2 = std::forward_as_tuple(x); // (2)
constexpr std::tuple<int&&> t3(1); // (3)
constexpr std::tuple<int> t4(1); // OK!
}
在上述代码中,静态断言通过了,但是第1到3行无法在gcc 4.9(由ubuntu提供)和clang中编译。它们抱怨变量没有通过
constexprs
初始化,x
不是constexpr
(即使它被文字初始化),它创建对临时值的引用或者它们的forward_as_tuple()
实现不是(尽管C++14标准确保这一点)。我正在处理一些大量使用
std::tuple
和constexpr
的代码。我可以绕过std::forward_as_tuple()
未定义为constexpr
,但我不明白为什么forward_as_tuple(0)
会返回一个tuple<int&&>
,这根据clang的说法创建了一个对临时值的引用,从而使其不是constexpr。替代方案对我需要的内容都不起作用--std::make_tuple()
不能用于完美转发,std::tie
不能存储字面值。 编辑:为什么std::forward_as_tuple()
以这种方式工作,并且没有提供替代方案?我是在做一些基本错误还是有些事情我不理解?
forward_as_tuple
返回std::tuple<Types&&...>
。您期望forward_as_tuple(0)
返回什么类型?比int
更适合的是哪个Types...
?即,你已经演示了会发生什么:你期望每行发生什么。它用于完美转发:返回引用或右值引用元组。如果需要,可以编写存储右值的元组,而且代码并不长。 - Yakk - Adam Nevraumontconstexpr int&& var = ..
。 - Jarod42std::forward_as_tuple(1,x,std::move(y))
,我会期望得到std::tuple<int,X&,Y>
。我不理解的是为什么std::forward_as_tuple
认为tuple<int&&, X& &&, Y&&>
更有用或更正确,并且没有提供一个版本,使得forward_as_tuple
对字面量有效。换句话说,似乎forward_as_tuple
实际上并没有正确地转发。 - SplinterOfChaos