如何在noexcept运算符中引用move构造函数

时间:2018-10-01 05:41:20

标签: c++ exception stl

我正在实现具有IsNothrowMoveConstructible属性的TypeInfo类。如果类型T的move构造函数标记为noexcept,我想将此参数设置为true。用noexcept(noexcept(T()))引用默认构造函数似乎可行,但是我还没有弄清楚如何引用move构造函数。我想解决方案将是这样的:

template <typename T> 
struct TypeInfo 
{
    enum
    {
        ...
        IsNothrowMoveConstructible = noexcept(noexcept(T(T&&))),
        ...
    };
};

我知道,我可以使用std :: is_nothrow_move_constructible,但我的目标是找出在这种情况下如何使用noexcept()运算符。

1 个答案:

答案 0 :(得分:1)

运算符noexcept()需要一个真实的表达式。不幸的是T(T&&)不是有效的表达式。

因此,您需要实例化T的出现并使用std::move()来确保它使用move构造函数(如果有)。这里是概念证明:

template <typename T> 
struct TypeInfo 
{
    bool test() 
    {
        T t;
        bool IsNothrowMoveConstructible = noexcept(T(std::move(t)));
        return IsNothrowMoveConstructible;
    };
};

问题是,这变得容易出错。如果T没有默认构造函数,它将无法编译。如果隐式或显式删除move构造函数,则相同。

但是如果您可以忍受这些缺陷,因为该值是在编译时确定的,因此是常量,则可以使用T成员并在枚举中定义一个常量:

struct TypeInfo 
{
    T t; 
    enum {
        IsNothrowMoveConstructible = noexcept(T(std::move(t)))
    }; 
};

这里是online demo