我有几个类,我想检查是否正在生成默认的移动构造函数.有没有办法检查这个(无论是编译时断言,还是解析生成的目标文件,还是别的东西)?
励志示例:
class MyStruct : public ComplicatedBaseClass {
std::vector<std::string> foo; // possibly huge
ComplicatedSubObject bar;
};
Run Code Online (Sandbox Code Playgroud)
如果任何类的任何基Complicated...Object类或成员的任何成员都不能被移动,MyStruct则不会生成其隐式移动构造函数,并且因此可能无法优化复制foo工作,即使foo可移动也可以进行移动.
我希望避免:
我已经尝试过以下内容但它们不起作用:
std::move明确使用- 如果没有可用的移动ctor,这将调用复制ctor.std::is_move_constructible-this将在复制构造函数接受时成功const Type&,默认情况下生成(只要移动构造函数未被显式删除,至少).nm -C以检查移动构造函数的存在[见下文].但是,另一种方法是可行的[见答案].我试着看一下像这样的普通类的生成符号:
#include <utility>
struct MyStruct {
MyStruct(int x) : x(x) {}
//MyStruct(const MyStruct& rhs) : x(rhs.x) {}
//MyStruct(MyStruct&& rhs) : x(rhs.x) {}
int x;
};
int main() {
MyStruct s1(4); …Run Code Online (Sandbox Code Playgroud) 在C++ 11中,如果自动阻止了隐式生成,则可以显式地默认特殊成员函数.
但是,显式默认默认特殊成员函数只会撤消由于手动声明某些其他特殊成员函数(复制操作,析构函数等)而导致的隐式删除,它不会强制编译器生成函数,并且代码被认为是即使实际上不能生成函数,也要很好地形成.
请考虑以下情形:
struct A
{
A () = default;
A (const A&) = default;
A (A&&) = delete; // Move constructor is deleted here
};
struct B
{
B () = default;
B (const B&) = default;
B (B&&) = default; // Move constructor is defaulted here
A a;
};
Run Code Online (Sandbox Code Playgroud)
B中的移动构造函数不会由编译器生成,因为这样做会导致编译错误(删除A的移动构造函数).在没有明确删除A的构造函数的情况下,B的移动构造函数将按预期生成(复制A,而不是移动它).
试图移动这样的对象将默默使用复制构造函数:
B b;
B b2 (std::move(b)); // Will call B's copy constructor
Run Code Online (Sandbox Code Playgroud)
有没有办法强制编译器生成函数或发出编译错误,如果它不能?如果没有这种保证,如果单个已删除的构造函数可以禁用整个对象层次结构的移动,则很难依赖默认的移动构造函数.
考虑以下:
template <class T>
struct myclass
{
using value_type = T;
constexpr myclass() = default;
constexpr myclass(const myclass& other) = default;
constexpr myclass(const myclass&& other) = default;
T value;
};
Run Code Online (Sandbox Code Playgroud)
myclass<int> x;初始化的整数0?myclass<std::vector<int>> x;默认移动构造函数的作用是什么?它是否称为向量的移动构造函数?