首页 > 解决方案 > 如何在 noexcept 运算符中引用移动构造函数

问题描述

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

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

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

标签: c++exceptionstl

解决方案


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

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

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

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

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

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

这里有一个在线演示


推荐阅读