noexcept表达式与类型特征

时间:2016-06-15 21:53:04

标签: c++ c++11

我正在学习如何使用条件noexcept并遇到这个问题。假设我有一个班级:

template<typename T>
class Wrapper {
public:
    Wrapper(T&& value) noexcept(/* ??? */)
        : value_(std::move(value))
    {}

private:
    T value_;
};

对于/* ??? */部分,我认为我们可以使用noexcept(T(std::move(value)))std::is_nothrow_move_constructible<T>::value,直到我偶然发现this

所以如果我使用noexcept(noexcept(T(std::move(value)))),严格来说我说“这个构造函数是noexcept iff构建并破坏 T是{{1} }}“?

虽然扔掉的破坏者应该被点燃并烧毁。

1 个答案:

答案 0 :(得分:6)

好问题,另见this language defect discussion。从它的名字可以清楚地看出std::is_nothrow_move_constructible<T>::value 应该只与rvalue的构造结构有关(但实际上也可能与破坏有关),而noexcept(T(std::move(value)))总是与两者有关建设和破坏。

因此,在您的情况下,避免未解决的std::is_nothrow_move_constructible特征问题的最省钱方法是使用新的位置,避免std::bad_alloc的问题(在Chris Beck的评论中提到),并且,类似地,使用T的析构函数作为包装器的析构函数。

template<typename T>
class Wrapper {
public:
    Wrapper(T&& value) noexcept(new(nullptr) T(std::move(value)))
        : value_(std::move(value))
    {}
    ~Wrapper() noexcept(noexcept(value_.T::~T()))
    {}
private:
    T value_;
};