c++ - 为什么 `std::forward_as_tuple(1)` 不是常量表达式?

标签 c++ c++14 stdtuple

#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 编译。他们提示变量没有被 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()以这种方式工作而不提供替代方案?

我是不是在做一些根本性的错误,还是有什么我不明白的地方?

最佳答案

std::forward_as_tuple以这种方式工作,因为它被指定返回一个引用元组以进行完美转发。如果你想要一个返回 std::tuple<int,X&,Y> 的函数当用 1 调用时, x , 和 std::move(y) ,然后写一个:

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

DEMO

关于c++ - 为什么 `std::forward_as_tuple(1)` 不是常量表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27788381/

相关文章:

c++ - 通过索引访问元组元素 c++11

c++ - typedef 和 enum 有什么区别

android - 从 pthread 初始化对象时为 "NoSuchMethodError"

c++ - 避免类范围,以便将成员函数作为函数指针传递

C++14 变量模板

c++ - 具有嵌套类型的类的概念

c++ - 将元组分配给类成员变量

C++ 动态类型构造和检测

c++ - 如何统计一个对象的引用次数?

c++ - 如何递归元组?