constexpr移动构造函数是否有意义
Does a constexpr move constructor ever make sense?
拥有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;
}
这并不是编译,因为尽管在c1
上调用std::move
,但编译器可以推论它需要使用(隐式删除)复制构造函数,而不是移动构造函数。我不确定为什么。
但是,如果我从c1
删除constexpr
,那么constexpr
移动构造函数将变得无法使用。
有什么办法可以使它起作用?还是constexpr
移动构造函数的一个不好的例子,但是有一个很好的例子?或者,拥有constexpr
移动构造函数总是错误的?
原则上,可以将移动构造函数与非const
对象一起使用,其寿命在评估常数表达式期间开始:
// C++14
constexpr int f() {
C a(/* ... */);
C b = std::move(a);
return 0;
}
constexpr int i = f();
可以在C 11中完成类似的事情,例如
constexpr C foo(C&& c) {
return std::move(c);
}
constexpr int f() {
return foo(C()), 0;
}
也就
这不会编译,因为尽管在
进行编译器。c1
上调用std::move
,但编译器仍需要使用(隐式删除)复制构造函数
c1
是类型C const
。当您move()
时,这确实是rvalue参考的铸件,因此您将获得C const&&
。请注意,它仍然是const
。当我们执行过载分辨率时,有三个构造函数:
C(std::array<int, 3> ); // not viable
C(C&& ); // not viable
C(C const& ) = delete; // viable!
C const&&
无法与C&&
结合,因为C const&
无法绑定到C&
。我们只剩下复制构造函数,该构造函数被隐式删除。
具有constexpr移动构造函数可能是有道理的 - 但是您要从"移动"的对象真的不能从中移动,因为它大概是const
。您可以添加const
移动构造函数:
constexpr C(C const&& other) : m_ar(other.m_ar) { }
这是一个荣耀的复制构造函数,但允许您想要的语法。也可以允许复制。
相关文章:
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- API 返回智能指针的 std::optional 以明确指定指针可能为 null 是否有意义?
- 从头开始为应用程序创建 docker 映像是否有意义?
- 插入向量时,使用lambda的返回而不是函数的返回是否有意义?
- 将 final 关键字添加到没有基类(未派生)的类中的虚函数是否有意义
- 左移负整数为零是否有意义?
- 是否有一个上下文表达式`a.b :: c`有意义
- 是否有一些有意义的统计数据来证明保持有符号整数算术溢出未定义是合理的
- 将可选与reference_wrapper相结合是否有意义?
- 函数返回rvalue参考是否有意义
- 将 [[noreturn]] 添加到主函数是否有意义
- 在shared_ptr的自定义删除器中检查 nullptr 是否有意义?
- 拥有一个没有构造函数的类是否有意义
- 这是否有意义,我的计算机只能并行运行4个线程
- constexpr移动构造函数是否有意义
- 为赋值编写伪代码,并希望仔细检查它是否有意义
- 在目标平台上编译 Boost 自己是否有意义
- 多层继承在C 中是否有意义
- 从 STL 容器继承并删除"新"运算符以防止由于缺少虚拟析构函数而导致未定义的行为是否有意义?
- 一元运算符关联是否有意义