gpt4 book ai didi

c++ - 如何检测一个类是否有移动构造函数?

转载 作者:太空狗 更新时间:2023-10-29 20:53:30 24 4
gpt4 key购买 nike

我想检测(并在 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

最佳答案

简短的回答:这是不可能的。

更多细节,基于@TobySpeight 的评论:

如果类不包含C(C&&) = delete; , 则无法检测是否包含C(C&&) { ... }与否:std::is_move_constructible<C>::value在任何一种情况下都为真,并且没有其他方法可以检测到它。

C(C&&) = delete; 的存在可以检测到:std::is_move_constructible<C>::value是假的当且仅当 C(C&&) = delete;存在。

更多解释在 this answer to "Understanding std::is_move_constructible " .

避免在 std::vector::push_back 中缓慢复制,不需要检测用户定义的移动构造函数。这是替代方案,基于@NirFriedman 的评论:

  • 所有类都有一个复制构造函数。
  • 旧 (C++98) 类具有成员交换和 0 参数构造函数(可以由编译器隐式生成),并且它们没有用户定义的移动构造函数。
  • 新 (C++11) 类没有成员交换(但它们可以有命名空间级交换或友元交换),并且它们有用户定义的移动构造函数。
  • 小类(我们不关心复制构造函数的速度,它总是足够快)可能有一个用户定义的移动构造函数。他们也可能有成员交换(但为了速度他们不应该)。如果它们有一个成员交换,它们也有一个 0 参数构造函数(可以由编译器隐式生成)。
  • SFINAE 用于检测成员交换。
    • 如果成员 swap 存在,则使用 resize + back + swap 向 vector 添加新元素。
    • 否则,使用 push_back。

对于旧类,这将使用成员交换(快速)。对于新类,它将使用移动构造函数(快,也快一点)。对于小类,它将使用复制构造函数(假设对于小类来说足够快)或移动构造函数(如果可用)。

这是我的最终快速解决方案 std::vector::push_back使用成员交换检测:https://github.com/pts/fast_vector_append/blob/master/fast_vector_append.h

关于c++ - 如何检测一个类是否有移动构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42423146/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com