When trying to construct a class which is supposed to hold a tuple created by calling std::forward_as_tuple I ran into the following error when compiling with clang(187537) and libc++:
/usr/include/c++/v1/tuple:329:11: error: rvalue reference to type 'int' cannot bind to lvalue of type 'int' : value(__t.get()) ^ ~~~~~~~~~ /usr/include/c++/v1/tuple:447:8: note: in instantiation of member function 'std::__1::__tuple_leaf<0, int &&, false>::__tuple_leaf' requested here struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...> ^ tuple.cpp:31:5: note: in instantiation of function template specialization 'make_foo2<int>' requested here make_foo2(1 + 1); ^ In file included from tuple.cpp:2: /usr/include/c++/v1/tuple:330:10: error: static_assert failed "Can not copy a tuple with rvalue reference member" {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy ... I was able to work around the above error by declaring the return type differently, but, from my understanding, it should have the same semantics so I would not expect it to stop the error. In the below code make_foo is the workaround which does not error out and make_foo2 causes the above error. I am able to successfully compile both versions using gcc 4.8.1 and the version of clang at coliru.
#include <utility> #include <tuple> template<class Tuple> struct foo { Tuple t; foo(Tuple &&t) : t(std::move(t)) { } }; template<class... Args> using ForwardedTuple = decltype(std::forward_as_tuple(std::forward<Args>(std::declval<Args>())...)); template<class... Args> foo<ForwardedTuple<Args...>> make_foo(Args&&... args) { return {std::forward_as_tuple(std::forward<Args>(args)...)}; } template<class... Args> auto make_foo2(Args&& ...args) -> decltype(foo<decltype(std::forward_as_tuple(std::forward<Args>(args)...))>(std::forward_as_tuple(std::forward<Args>(args)...))) { return foo<decltype(std::forward_as_tuple(std::forward<Args>(args)...))>(std::forward_as_tuple(std::forward<Args>(args)...)); } int main() { make_foo(1 + 1); make_foo2(1 + 1); } What is the difference between the above make_foo functions and is make_foo2 incorrect?
Thanks.
std::forward_as_tuplecreates a tupel ofrvaluereferences (orlvaluereferences). Is that what you want?cout << std::get<0>(make_foo(1 + 1).t) << endl;make_fooandmake_foo2compile at coliru's clang++ and g++ butmake_foo2does not compile on your own clang++ with libc++?make_fooandmake_foo2is thatmake_foodoesn't requirefoo<...>to have either a copy or move ctor (none is required). See this answer and the comments to it.