3
#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!
}

在上面的代码中,static_assert 通过了,但是第 1 行到第 3 行无法使用 gcc 4.9(由 ubuntu 提供)和 clang 编译。他们抱怨变量不是由 初始化的constexprsx不是 a constexpr(即使它是由文字初始化的),而是创建对临时的引用或者它们的实现forward_as_tuple()不是(尽管 C++14 标准确实保证了这一点)。

我正在编写一些大量使用std::tupleand的代码constexpr。我可以绕过std::forward_as_tuple()不被定义为constexpr,但我不明白为什么forward_as_tuple(0)会返回 a tuple<int&&>,根据 clang 创建一个对临时的引用,使其不是 constexpr。替代品不能满足我的需要——std::make_tuple()不能用于完美转发,std::tie也不能存储文字值。编辑:为什么std::forward_as_tuple()以这种方式工作而不提供替代方案?

我在这里做一些根本错误的事情还是有什么我不明白的?

4

1 回答 1

0

std::forward_as_tuple之所以这样工作,是因为它被指定返回一个引用元组以进行完美转发。如果您想要一个在使用、和std::tuple<int,X&,Y>调用时返回的函数,请编写一个:1xstd::move(y)

template <typename...Ts>
constexpr std::tuple<Ts...> foo(Ts&&...ts) {
  return std::tuple<Ts...>{std::forward<Ts>(ts)...};
}

演示

于 2015-01-06T05:29:57.523 回答