gpt4 book ai didi

c++ - 使用 Auto 时在派生类中使用虚拟析构函数强制复制构造函数

转载 作者:行者123 更新时间:2023-11-28 04:45:39 24 4
gpt4 key购买 nike

我在尝试派生 std::unique_lock 时遇到了一个问题,否则我无法用更简单的类进行复制。下面是复制问题的可编译代码:

#include <iostream>
#include <mutex>
#include <string>

template<class T>
class A : public std::unique_lock<T>
{
public:
template<typename... Args>
A(const std::string name, Args&&... args) : name_(name),
std::unique_lock<T>(args...) { }
virtual ~A() {} // if this destructor exists...
private:
std::string name_;
};


int main()
{
std::timed_mutex tm;
auto a = A<std::timed_mutex>("Hello", tm, std::defer_lock); // this line fails
A<std::timed_mutex> a("Hello", tm, std::defer_lock); // this line works
return 0;
}

如果虚拟析构函数存在(我的实际类需要它),那么我不能使用带有 auto 的行来实例化该类,因为最终调用 std::unique_lock 中的构造函数是已删除的构造函数,它采用 const T&被删除的互斥量(b/c 锁类不能处理 const 互斥量)。我假设它的调用删除了 const ctor,因为出于某种原因,它调用 A() 中的复制构造函数,该构造函数将 const &A 作为输入(根据下面的错误日志)。如果我只是使用非自动样式实例化代码(已标记),那么它编译得很好。

我正在使用 gcc 5.4.1设置(CMAKE_CXX_STANDARD 11)设置。我也尝试过 14 和 17,所以我假设它不是我使用的 cpp。

最佳答案

如果您的类包含用户声明的析构函数、复制构造函数或赋值运算符,编译器将不会隐式生成移动构造函数。由于 A 没有移动构造函数,编译器回退到复制构造函数,它被隐式删除,因为 std::unique_lock 的复制构造函数被删除。

您可以显式声明一个移动构造函数来让事情正常进行:

template<class T>
class A : public std::unique_lock<T>
{
public:
template<typename... Args>
A(const std::string name, Args&&... args)
: std::unique_lock<T>(args...),
name_(name)
{ }
A(A&&) = default;
virtual ~A() {}
private:
std::string name_;
};

Live example

您可能还应该声明一个移动赋值运算符,但在这种情况下没有必要。

关于c++ - 使用 Auto 时在派生类中使用虚拟析构函数强制复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49333107/

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