繁体   English   中英

包括不可移动可构造字段的类型如何可移动可构造?

[英]How could type, comprising non move constructible field, be move constructible?

是这个问题的根源

在使用clang ++ / libc ++和g ++ / libstdc ++编译以下代码时,我有不同的行为。

#include <type_traits>
#include <utility>
#include <iostream>

int main()
{
    using array_t = int[42];
    std::cout << "array_t:" << std::endl;
    std::cout << "    is_move_constructible: " << std::is_move_constructible<array_t>::value << std::endl;
    std::cout << "    is_move_assignable:    " << std::is_move_assignable<array_t>::value    << std::endl;
    std::cout << std::endl;

    using pair_t = std::pair<array_t, array_t>;
        std::cout << "pair_t:" << std::endl;
    std::cout << "    is_move_constructible: " << std::is_move_constructible<pair_t>::value << std::endl;
    std::cout << "    is_move_assignable:    " << std::is_move_assignable<pair_t>::value    << std::endl;
    std::cout << std::endl;

    pair_t p1;
    pair_t p2(std::move(p1));

    return 0;
}

lang声(失败):

In file included from /home/soon/Src/C++/main/main.cpp:2:
/usr/include/c++/v1/utility:283:11: error: array initializer must be an initializer list
        : first(_VSTD::forward<first_type>(__p.first)),
          ^
/home/soon/Src/C++/main/main.cpp:20:12: note: in instantiation of member function 'std::__1::pair<int [42], int [42]>::pair' requested here
    pair_t p2(std::move(p1));
           ^
In file included from /home/soon/Src/C++/main/main.cpp:2:
/usr/include/c++/v1/utility:284:11: error: array initializer must be an initializer list
          second(_VSTD::forward<second_type>(__p.second))
          ^

g ++编译没有错误。 输出为:

array_t:
    is_move_constructible: 0
    is_move_assignable:    0

pair_t:
    is_move_constructible: 1
    is_move_assignable:    1

我无法确定,这是正确的。 我猜想,如果一个类包含不可移动构造的字段,则不能使用移动技术来构造它。 那是对的吗?

我不知道GCC(或更确切地说libstdc ++)是否允许使用此代码,但是如果是这样,那么结果是正确的。 如果所有成员都具有自己的move构造函数或可以被简单复制,则将生成默认的move构造函数。 Pair的move构造函数被指定为默认值,因此它遵循以下规则。 它们的基元和数组都是可复制的。

我怀疑libstdc ++是正确的,由于某种原因,您正在libc ++中进入_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS的编译器兼容性分支,该分支不支持数组,因为它不使用= default 您正在使用什么版本的Clang,并且正确指定了-std=c++11

我应该补充一下塞巴斯蒂安的答案,即clang-3.3编译没有问题的代码,其结果(在运行时)与gcc相同。 因此,您的clang编译器版本的不当行为似乎是一个错误,目前已修复。

类型特征可能有些棘手。 is_move_constructible/assignable检查类型是否包含移动构造函数/赋值运算符(显式或隐式定义)。 而已。 这些类型特征无法检测到这些构造函数/运算符的实际实例是否格式错误。

由于std::pair包含移动构造函数/赋值运算符,因此is_move_constructibleis_move_assignable都将为std::true_type 这仅表示已定义它们,但这并不意味着您可以实际使用它们。

这已经在讨论这个线程

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM