C++ 使用void复制和交换习惯用法显式模板类时出错
给定模板类C++ 使用void复制和交换习惯用法显式模板类时出错,c++,templates,C++,Templates,给定模板类Foo: 编辑2 类的完整源代码: template<class T> class Future { MARK_UNCOPYABLE(Future<T>) public: Future() : mMutex{}, mDoneCondition{}, mDone{ false }, mCancelled{ false },
Foo
:
编辑2
类的完整源代码:
template<class T>
class Future
{
MARK_UNCOPYABLE(Future<T>)
public:
Future() :
mMutex{},
mDoneCondition{},
mDone{ false },
mCancelled{ false },
mValue{}
{
}
Future(Future<T> &&aOther) noexcept :
Future{}
{
swap(*this, aOther);
}
virtual ~Future() = 0;
Future<T> &operator=(Future<T> &&aOther) noexcept
{
swap(*this, aOther);
return (*this);
}
virtual bool cancel()
{
bool cancelPending = false;
{
std::lock_guard<std::mutex> lock{ this->mMutex };
if (!this->mDone && !this->mCancelled)
{
this->mCancelled = true;
cancelPending = true;
}
}
bool result = false;
if (cancelPending)
{
handleCancel();
{
std::lock_guard<std::mutex> lock{ this->mMutex };
this->mDoneCondition.notify_all();
result = !this->mDone;
}
}
return result;
}
bool getValue(T &aOutValue)
{
std::unique_lock<std::mutex> lock{ this->mMutex };
while (!this->mDone && !this->mCancelled)
{
this->mDoneCondition.wait(lock);
}
if (this->mDone)
{
aOutValue = this->mValue;
}
return this->mDone;
}
template<class Rep, class Period>
bool getValueFor(T &aOutValue, const std::chrono::duration<Rep, Period> &aTimeoutDuration)
{
std::unique_lock<std::mutex> lock{ this->mMutex };
bool waiting = true;
while (!this->mDone && !this->mCancelled && waiting)
{
waiting = this->mDoneCondition.wait_for(lock, aTimeoutDuration);
}
if (this->mDone)
{
aOutValue = this->mValue;
}
return this->mDone;
}
template<class Clock, class Duration>
bool getValueUntil(T &aOutValue, const std::chrono::time_point<Clock, Duration> &aTimeoutTime)
{
std::unique_lock<std::mutex> lock{ this->mMutex };
bool waiting = true;
while (!this->mDone && !this->mCancelled && waiting)
{
waiting = this->mDoneCondition.wait_until(lock, aTimeoutTime);
}
if (this->mDone)
{
aOutValue = this->mValue;
}
return this->mDone;
}
void setValue(const T &aValue)
{
std::lock_guard<std::mutex> lock{ this->mMutex };
if (this->mDone)
{
throw std::runtime_error("Value already set");
}
this->mValue = aValue;
this->mDone = true;
this->mDoneCondition.notify_all();
}
inline void setValue(T &&aValue)
{
setValue(std::forward<T>(aValue));
}
inline bool isCancelled() const
{
return this->mCancelled;
}
inline bool isDone() const
{
return this->mDone;
}
friend void swap(Future<T> &aFirst, Future<T> &aSecond)
{
std::unique_lock<std::mutex> lock1(aFirst.mMutex, std::defer_lock);
std::unique_lock<std::mutex> lock2(aSecond.mMutex, std::defer_lock);
try
{
std::lock(lock1, lock2);
using std::swap;
aFirst.mDone = aSecond.mDone.load();
aFirst.mCancelled = aSecond.mCancelled.load();
swap(aFirst.mValue, aSecond.mValue)
}
catch (std::system_error)
{
// Do nothing
}
}
protected:
virtual void handleCancel() = 0;
private:
std::mutex mMutex;
std::condition_variable mDoneCondition;
std::atomic<bool> mDone;
std::atomic<bool> mCancelled;
T mValue;
};
template<class T>
Future<T>::~Future() = default;
template<>
class Future<void>
{
MARK_UNCOPYABLE(Future)
public:
Future() :
mMutex{},
mDoneCondition{},
mDone{ false },
mCancelled{ false }
{
}
Future(Future<void> &&aOther) noexcept :
Future{}
{
swap(*this, aOther);
}
virtual ~Future() = 0;
Future<void> &operator=(Future<void> &&aOther) noexcept
{
swap(*this, aOther);
return (*this);
}
virtual bool cancel()
{
bool cancelPending = false;
{
std::lock_guard<std::mutex> lock{ this->mMutex };
if (!this->mDone && !this->mCancelled)
{
this->mCancelled = true;
cancelPending = true;
}
}
bool result = false;
if (cancelPending)
{
handleCancel();
{
std::lock_guard<std::mutex> lock{ this->mMutex };
this->mDoneCondition.notify_all();
result = !this->mDone;
}
}
return result;
}
bool getValue()
{
std::unique_lock<std::mutex> lock{ this->mMutex };
while (!this->mDone && !this->mCancelled)
{
this->mDoneCondition.wait(lock);
}
return this->mDone;
}
template<class Rep, class Period>
bool getValueFor(const std::chrono::duration<Rep, Period> &aTimeoutDuration)
{
std::unique_lock<std::mutex> lock{ this->mMutex };
bool waiting = true;
while (!this->mDone && !this->mCancelled && waiting)
{
waiting = this->mDoneCondition.wait_for(lock, aTimeoutDuration);
}
return this->mDone;
}
template<class Clock, class Duration>
bool getValueUntil(const std::chrono::time_point<Clock, Duration> &aTimeoutTime)
{
std::unique_lock<std::mutex> lock{ this->mMutex };
bool waiting = true;
while (!this->mDone && !this->mCancelled && waiting)
{
waiting = this->mDoneCondition.wait_until(lock, aTimeoutTime);
}
return this->mDone;
}
void setValue()
{
std::lock_guard<std::mutex> lock{ this->mMutex };
if (this->mDone)
{
throw std::runtime_error("Value already set");
}
this->mDone = true;
this->mDoneCondition.notify_all();
}
inline bool isCancelled() const
{
return this->mCancelled;
}
inline bool isDone() const
{
return this->mDone;
}
friend void swap(Future<void> &aFirst, Future<void> &aSecond) noexcept
{
std::unique_lock<std::mutex> lock1(aFirst.mMutex, std::defer_lock);
std::unique_lock<std::mutex> lock2(aSecond.mMutex, std::defer_lock);
try
{
std::lock(lock1, lock2);
using std::swap;
aFirst.mDone = aSecond.mDone.load();
aFirst.mCancelled = aSecond.mCancelled.load();
}
catch (std::system_error)
{
// Do nothing
}
}
protected:
virtual void handleCancel() = 0;
private:
std::mutex mMutex;
std::condition_variable mDoneCondition;
std::atomic<bool> mDone;
std::atomic<bool> mCancelled;
};
模板
班级未来
{
MARK_不可复制(未来)
公众:
Future():
mMutex{},
mDoneCondition{},
mDone{false},
McCancelled{false},
mValue{}
{
}
未来(未来和未来)无例外:
未来{}
{
交换(*这个,另一个);
}
虚拟~Future()=0;
Future&operator=(Future&aOther)无例外
{
交换(*这个,另一个);
返回(*本条);
}
虚拟布尔取消()
{
bool cancelPending=false;
{
std::lock_guard lock{this->mMutex};
如果(!this->mDone&!this->mCancelled)
{
此->McCancell=true;
cancelPending=true;
}
}
布尔结果=假;
如果(取消挂起)
{
handleCancel();
{
std::lock_guard lock{this->mMutex};
此->mDoneCondition.notify_all();
结果=!this->mDone;
}
}
返回结果;
}
bool getValue(T&aOutValue)
{
std::unique_lock lock{this->mMutex};
而(!this->mDone&!this->mCancelled)
{
此->mDoneCondition.wait(锁定);
}
如果(此->mDone)
{
aOutValue=此->mValue;
}
返回此->mDone;
}
模板
bool getValueFor(T&aOutValue,const std::chrono::duration和aTimeoutDuration)
{
std::unique_lock lock{this->mMutex};
布尔等待=真;
而(!this->mDone&&!this->mCancelled&&waiting)
{
waiting=this->mDoneCondition.wait_for(lock,aTimeoutDuration);
}
如果(此->mDone)
{
aOutValue=此->mValue;
}
返回此->mDone;
}
模板
bool getValueUntil(T&aOutValue,const std::chrono::time\u point&aTimeoutTime)
{
std::unique_lock lock{this->mMutex};
布尔等待=真;
而(!this->mDone&&!this->mCancelled&&waiting)
{
waiting=this->mDoneCondition.等待(lock,aTimeoutTime);
}
如果(此->mDone)
{
aOutValue=此->mValue;
}
返回此->mDone;
}
无效设置值(常数T和值)
{
std::lock_guard lock{this->mMutex};
如果(此->mDone)
{
抛出std::runtime_错误(“值已设置”);
}
此->mValue=aValue;
这->mDone=true;
此->mDoneCondition.notify_all();
}
内联无效设置值(T&&aValue)
{
设置值(标准::转发(aValue));
}
内联bool isCancelled()常量
{
返回此->已取消;
}
内联bool isDone()常量
{
返回此->mDone;
}
朋友无效交换(未来和第一次、未来和第二次)
{
std::unique_lock 1(affirst.mMutex,std::defer_lock);
std::unique_lock 2(aSecond.mMutex,std::defer_lock);
尝试
{
锁(锁1,锁2);
使用std::swap;
affirst.mDone=aSecond.mDone.load();
affirst.mCancelled=aSecond.mCancelled.load();
交换(第一个MVValue,第二个MVValue)
}
捕获(标准::系统错误)
{
//无所事事
}
}
受保护的:
虚拟void handleCancel()=0;
私人:
std::互斥mMutex;
std::condition_变量mDoneCondition;
std::原子mDone;
std::原子mc取消;
T值;
};
模板
Future::~Future()=默认值;
模板
班级未来
{
MARK_不可复制(未来)
公众:
Future():
mMutex{},
mDoneCondition{},
mDone{false},
McCancelled{false}
{
}
未来(未来和未来)无例外:
未来{}
{
交换(*这个,另一个);
}
虚拟~Future()=0;
Future&operator=(Future&aOther)无例外
{
交换(*这个,另一个);
返回(*本条);
}
虚拟布尔取消()
{
bool cancelPending=false;
{
std::lock_guard lock{this->mMutex};
如果(!this->mDone&!this->mCancelled)
{
此->McCancell=true;
cancelPending=true;
}
}
布尔结果=假;
如果(取消挂起)
{
handleCancel();
{
std::lock_guard lock{this->mMutex};
此->mDoneCondition.notify_all();
结果=!this->mDone;
}
}
返回结果;
}
bool getValue()
{
std::unique_lock lock{this->mMutex};
而(!this->mDone&!this->mCancelled)
{
此->mDoneCondition.wait(锁定);
}
返回此->mDone;
}
模板
bool getValueFor(const std::chrono::duration和aTimeoutDuration)
{
std::unique_lock lock{this->mMutex};
布尔等待=真;
而(!this->mDone&&!this->mCancelled&&waiting)
{
等待=这个
template<>
class Foo<void>
{
public:
friend void swap(Foo<void> &aFirst, Foo<void> &aSecond)
{
using std::swap;
...
}
}
Foo(Foo<void> &&aOther) noexcept :
Foo{}
{
swap(*this, aOther);
}
template<class T>
class Future
{
MARK_UNCOPYABLE(Future<T>)
public:
Future() :
mMutex{},
mDoneCondition{},
mDone{ false },
mCancelled{ false },
mValue{}
{
}
Future(Future<T> &&aOther) noexcept :
Future{}
{
swap(*this, aOther);
}
virtual ~Future() = 0;
Future<T> &operator=(Future<T> &&aOther) noexcept
{
swap(*this, aOther);
return (*this);
}
virtual bool cancel()
{
bool cancelPending = false;
{
std::lock_guard<std::mutex> lock{ this->mMutex };
if (!this->mDone && !this->mCancelled)
{
this->mCancelled = true;
cancelPending = true;
}
}
bool result = false;
if (cancelPending)
{
handleCancel();
{
std::lock_guard<std::mutex> lock{ this->mMutex };
this->mDoneCondition.notify_all();
result = !this->mDone;
}
}
return result;
}
bool getValue(T &aOutValue)
{
std::unique_lock<std::mutex> lock{ this->mMutex };
while (!this->mDone && !this->mCancelled)
{
this->mDoneCondition.wait(lock);
}
if (this->mDone)
{
aOutValue = this->mValue;
}
return this->mDone;
}
template<class Rep, class Period>
bool getValueFor(T &aOutValue, const std::chrono::duration<Rep, Period> &aTimeoutDuration)
{
std::unique_lock<std::mutex> lock{ this->mMutex };
bool waiting = true;
while (!this->mDone && !this->mCancelled && waiting)
{
waiting = this->mDoneCondition.wait_for(lock, aTimeoutDuration);
}
if (this->mDone)
{
aOutValue = this->mValue;
}
return this->mDone;
}
template<class Clock, class Duration>
bool getValueUntil(T &aOutValue, const std::chrono::time_point<Clock, Duration> &aTimeoutTime)
{
std::unique_lock<std::mutex> lock{ this->mMutex };
bool waiting = true;
while (!this->mDone && !this->mCancelled && waiting)
{
waiting = this->mDoneCondition.wait_until(lock, aTimeoutTime);
}
if (this->mDone)
{
aOutValue = this->mValue;
}
return this->mDone;
}
void setValue(const T &aValue)
{
std::lock_guard<std::mutex> lock{ this->mMutex };
if (this->mDone)
{
throw std::runtime_error("Value already set");
}
this->mValue = aValue;
this->mDone = true;
this->mDoneCondition.notify_all();
}
inline void setValue(T &&aValue)
{
setValue(std::forward<T>(aValue));
}
inline bool isCancelled() const
{
return this->mCancelled;
}
inline bool isDone() const
{
return this->mDone;
}
friend void swap(Future<T> &aFirst, Future<T> &aSecond)
{
std::unique_lock<std::mutex> lock1(aFirst.mMutex, std::defer_lock);
std::unique_lock<std::mutex> lock2(aSecond.mMutex, std::defer_lock);
try
{
std::lock(lock1, lock2);
using std::swap;
aFirst.mDone = aSecond.mDone.load();
aFirst.mCancelled = aSecond.mCancelled.load();
swap(aFirst.mValue, aSecond.mValue)
}
catch (std::system_error)
{
// Do nothing
}
}
protected:
virtual void handleCancel() = 0;
private:
std::mutex mMutex;
std::condition_variable mDoneCondition;
std::atomic<bool> mDone;
std::atomic<bool> mCancelled;
T mValue;
};
template<class T>
Future<T>::~Future() = default;
template<>
class Future<void>
{
MARK_UNCOPYABLE(Future)
public:
Future() :
mMutex{},
mDoneCondition{},
mDone{ false },
mCancelled{ false }
{
}
Future(Future<void> &&aOther) noexcept :
Future{}
{
swap(*this, aOther);
}
virtual ~Future() = 0;
Future<void> &operator=(Future<void> &&aOther) noexcept
{
swap(*this, aOther);
return (*this);
}
virtual bool cancel()
{
bool cancelPending = false;
{
std::lock_guard<std::mutex> lock{ this->mMutex };
if (!this->mDone && !this->mCancelled)
{
this->mCancelled = true;
cancelPending = true;
}
}
bool result = false;
if (cancelPending)
{
handleCancel();
{
std::lock_guard<std::mutex> lock{ this->mMutex };
this->mDoneCondition.notify_all();
result = !this->mDone;
}
}
return result;
}
bool getValue()
{
std::unique_lock<std::mutex> lock{ this->mMutex };
while (!this->mDone && !this->mCancelled)
{
this->mDoneCondition.wait(lock);
}
return this->mDone;
}
template<class Rep, class Period>
bool getValueFor(const std::chrono::duration<Rep, Period> &aTimeoutDuration)
{
std::unique_lock<std::mutex> lock{ this->mMutex };
bool waiting = true;
while (!this->mDone && !this->mCancelled && waiting)
{
waiting = this->mDoneCondition.wait_for(lock, aTimeoutDuration);
}
return this->mDone;
}
template<class Clock, class Duration>
bool getValueUntil(const std::chrono::time_point<Clock, Duration> &aTimeoutTime)
{
std::unique_lock<std::mutex> lock{ this->mMutex };
bool waiting = true;
while (!this->mDone && !this->mCancelled && waiting)
{
waiting = this->mDoneCondition.wait_until(lock, aTimeoutTime);
}
return this->mDone;
}
void setValue()
{
std::lock_guard<std::mutex> lock{ this->mMutex };
if (this->mDone)
{
throw std::runtime_error("Value already set");
}
this->mDone = true;
this->mDoneCondition.notify_all();
}
inline bool isCancelled() const
{
return this->mCancelled;
}
inline bool isDone() const
{
return this->mDone;
}
friend void swap(Future<void> &aFirst, Future<void> &aSecond) noexcept
{
std::unique_lock<std::mutex> lock1(aFirst.mMutex, std::defer_lock);
std::unique_lock<std::mutex> lock2(aSecond.mMutex, std::defer_lock);
try
{
std::lock(lock1, lock2);
using std::swap;
aFirst.mDone = aSecond.mDone.load();
aFirst.mCancelled = aSecond.mCancelled.load();
}
catch (std::system_error)
{
// Do nothing
}
}
protected:
virtual void handleCancel() = 0;
private:
std::mutex mMutex;
std::condition_variable mDoneCondition;
std::atomic<bool> mDone;
std::atomic<bool> mCancelled;
};