我想检测(并使用std::enable_if
中的结果)C ++类是否定义了移动构造函数。
以下程序打印MOVE
,因此使用std::is_move_constructible
不是这样做的方法:
#include <stdio.h>
#include <type_traits>
class C {
public:
C() { puts("C()"); }
C(int) { puts("C(int)"); }
~C() { puts("~C()"); }
C(const C&) { puts("C(const C&)"); }
// C(C&&) { puts("C(C&&)"); }
C& operator=(const C&) { puts("C="); return *this; }
};
int main(int argc, char** argv) {
(void)argc; (void)argv;
if (std::is_move_constructible<C>::value) puts("MOVE");
return 0;
}
我需要一个仅在我取消注释包含MOVE
的行时打印&&
的程序。
答案 0 :(得分:4)
简短回答:这是不可能的。
更多细节,基于@TobySpeight的评论:
如果该类不包含C(C&&) = delete;
,则无法检测它是否包含C(C&&) { ... }
:std::is_move_constructible<C>::value
在任何一种情况下均为真,并且没有其他方式检测它。
可以检测到C(C&&) = delete;
的存在:如果std::is_move_constructible<C>::value
存在,则C(C&&) = delete;
为false。
this answer to "Understanding std::is_move_constructible
"中的更多解释。
为了避免在std::vector::push_back
中进行慢速复制,不需要检测用户定义的移动构造函数。根据@ NirFriedman的评论,这是另一种选择:
对于旧类,这将使用成员交换(快速)。对于新类,它将使用移动构造函数(快速,也快一点)。对于小类,它将使用复制构造函数(假设对于小类来说足够快)或移动构造函数(如果可用)。
以下是我使用成员交换检测的快速std::vector::push_back
的最终解决方案:https://github.com/pts/fast_vector_append/blob/master/fast_vector_append.h