is_copy_constructible typetrait 给出了错误的答案

is_copy_constructible typetrait gives wrong answer

在下面的代码中,is_copy_constructible_v returns 正确,但是 MainClass 的复制构造函数被标记为已删除。

尝试调用复制构造函数是一个编译错误。
is_copy_constructible_v怎么看不到呢?

class BaseClass {};

class MainClass : public BaseClass {
public:
    MainClass(MainClass&) = delete;

    MainClass(const BaseClass& rhs)
    {
    }
};

int main()
{
    MainClass first{{}};

    //This line will not compile because MainClass::MainClass(MainClass&) is a deleted function
    //MainClass second{first};

    auto mainclass_is_constructible = std::is_copy_constructible_v<MainClass>;

    //This assert fails because is_copy_constructible_v returns true
    static_assert((std::is_copy_constructible_v<MainClass>) == 0);
}

这是通过检查给定 class 是否为 copyable/movable 的单元测试发现的。
它们工作正常,但在实际代码中添加 MainClass(const BaseClass& rhs) 的等价物后就不行了。

如果我们有 MainClass(const BaseClass& rhs, int value),那么 is_copy_constructible_v 就可以了。

给定 std::vector<MainClass>,如果我们也删除走法 ctor/assignment,会发生什么情况?向量不会利用 is_copy_constructible_v 来检测如何最好地操作,并收到错误的答案吗?

非常感谢

MainClass 有一个 MainClass::MainClass(const BaseClass& rhs),这使得从 const 左值构造 MainClass 成为可能,例如

const MainClass first{{}};

// This line will compile because MainClass::MainClass(const BaseClass& rhs) is usable
// a MainClass could be bound to const BaseClass&
MainClass second{first};

并且 std::is_copy_constructible 执行检查为:

provides a member constant value equal to std::is_constructible<T, const T&>::value.

请注意,它正在检查是否可以从 const T& 构造 T,然后它会为 MainClass 生成 true

如果将复制构造函数声明为:

MainClass(const MainClass&) = delete;

你会得到结果false

What would happen given an std::vector<MainClass>

它将使用 MainClass::MainClass(const BaseClass& rhs)(用于 push_back 或重新分配等)。如果不是您所期望的,则必须重新考虑设计。