Why isn't `std :: forward_as_tuple (1)` constant expression?

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

      

In the above code, this static_assert goes through, however lines 1 through 3 will not compile with both gcc 4.9 (shipped with ubuntu) and clang. They complain that variables are not initialized constexprs

, that x

it is not constexpr

(even if it is initialized with a literal), that is, it creates a reference to a temporary, or that their implementation forward_as_tuple()

is equal (although the C ++ 14 standard guarantees this).

I am working on some code that makes heavy use of std::tuple

and constexpr

. I can get around std::forward_as_tuple()

not being defined as constexpr

, but I can't figure out why forward_as_tuple(0)

will return tuple<int&&>

, which, according to clang, creates a reference to the temporary creation of this non constexpr. The alternatives don't work for what I need - std::make_tuple()

cannot be used for perfect forwarding, and std::tie

cannot store literal values. Edit: Why std::forward_as_tuple()

works this way and doesn't offer alternatives?

Am I doing something fundamentally wrong here or is there something I don't understand?

+3


source to share


1 answer


std::forward_as_tuple

works like this because it is defined to return a tuple of links for perfect forwarding. If you want a function that returns std::tuple<int,X&,Y>

when called with 1

, x

and std::move(y)

then write one:

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

      



DEMO

0


source







All Articles