c++ - 使用包含右值引用的成员元组构造类

标签 c++ c++11

当试图构建一个类,该类应该包含通过调用 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是不是不正确?

谢谢。

最佳答案

看起来你从 make_foo2 返回了 foo<>。但是 foo 没有生成移动构造函数(编译器不会生成它)。因此复制构造函数被调用,编译因此失败。

关于c++ - 使用包含右值引用的成员元组构造类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18369640/

相关文章:

c++ - 在 C++ 中对排列进行排序的最便宜的方法是什么?

c++ - 给定第一象限中的坐标列表,计算可以形成多少个单边平行于 x 轴的直角三角形

c++ - QWidget 中的 SDL_Surface

c++ - 比较 vector 的元素

c++ - 在模板类中使用 r 和 l 值构造函数时出错

c++ - 如何在编译时计算梅森数

c++ - 将 typeid().hash_code() 存储为 16 位整数

c++ - 如何使用 QGraphicsScene::setStyle()?

C++ 从 std::vector<std::function<...>> 中删除 std::function

c++ - zmq::proxy 示例不起作用 ()