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;
};