当试图构造一个应该保存通过调用std::forward_as_tuple
创建的元组的类时,在使用clang(187537)和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 ...
我能够通过不同地声明返回类型来解决上述错误,但是,从我的理解,它应该具有相同的语义,所以我不希望它停止错误。在下面的代码中make_foo
是没有错误输出的解决方法,make_foo2导致上述错误。我能够使用gcc 4.8.1和coliru处的clang版本成功编译两个版本。
#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);
}
上述make_foo
函数之间的区别是make_foo2
是不正确的?
感谢。
答案 0 :(得分:1)
看起来你回来了foo&lt;&gt;来自make_foo2。但是foo没有生成移动构造函数(编译器不会生成它)。因此,调用复制构造函数并因此编译失败。