constexpr移动构造函数是否有意义?

Dan*_*nra 6 c++ move-constructor constexpr c++11

有一个constexpr移动构造函数是否有意义?

例如,请考虑以下事项:

#include <array>

class C
{
public:
    constexpr C(std::array<int, 3> ar) : m_ar{ar} {}
    constexpr C(C&& other) : m_ar{std::move(other.m_ar)} { }
private:
    std::array<int, 3> m_ar;
};

int main()
{
    constexpr C c1 {{{1, 2, 3}}};
    constexpr C c2{std::move(c1)};
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这不编译,因为尽管调用std::movec1,编译器推断它需要使用(隐含删除)拷贝构造函数,而不是移动构造函数.我不知道为什么.

但是如果我删除了constexprfrom c1,那么constexpr移动构造函数就会变得无法使用.

有没有办法让这个工作?或者这是一个constexpr移动构造函数的坏例子,但是有很好的例子吗?或者,拥有constexpr移动构造函数总是错误的吗?

T.C*_*.C. 3

const原则上,移动构造函数可以与生命周期在常量表达式求值期间开始的非对象一起使用:

// C++14
constexpr int f() {
    C a(/* ... */);
    C b = std::move(a);
    return 0;
}
constexpr int i = f();
Run Code Online (Sandbox Code Playgroud)

类似的事情可以在 C++11 中完成,例如

constexpr C foo(C&& c) { 
    return std::move(c); 
}

constexpr int f() { 
    return foo(C()), 0; 
}
Run Code Online (Sandbox Code Playgroud)

也就是说,由于常量表达式中使用的所有内容都必须是可简单破坏的,因此移动构造函数的用处相当有限。