【问题标题】:static_assert in templated member function of non-template class非模板类的模板化成员函数中的 static_assert
【发布时间】:2023-01-10 10:00:50
【问题描述】:

在过去的几天里,我终于切换到了 MSVC 2022,并且从之前运行良好的代码中获得了 static_assert。

我有一个类型需要根据模板参数类型是否可三重构造和破坏来以不同方式实现成员,但尚未实际实现任何该逻辑。我一直在使用 static_assert(false, "not yet implemented") 来防止意外使用该成员。

我已将其简化为以下示例:

#include <type_traits>

class TestClass
{
    size_t MemberFn() { /* shared stuff between trivial and non-trivial */
        return 0;
    }
    template<typename Type>
    size_t MemberFn(std::enable_if_t<!std::is_trivially_constructible_v<Type> || !std::is_trivially_destructible_v<Type>>* = nullptr)
    {
        static_assert(false, "not implemented yet");
        return 0;
    }
    template<typename Type>
    size_t MemberFn(std::enable_if_t<std::is_trivially_constructible_v<Type> && std::is_trivially_destructible_v<Type>>* = nullptr)
    {
        static_assert(false, "not implemented yet");
        return 0;
    }
};

当我尝试构建它时,我得到以下信息(和第二个成员模板类似):

2>D:\projects\TestLib\TestLib\testlib.h(18,17): error C2338: static_assert failed: 'not implemented yet'
2>D:\projects\TestLib\TestLib\testlib.h(16,9): message : This diagnostic occurred in the compiler generated function 'size_t TestClass::MemberFn(enable_if<!std::is_trivially_constructible_v<Type,>||!std::is_trivially_destructible_v<Type>,void>::type *)'

请注意,我实际上并没有在任何地方调用此函数,并且诊断没有告诉我编译器尝试使用的实际类型。基本上我希望回到这个被忽略的特定函数,就像它在 MSVC 2019 中所做的那样。

我正在使用 /std:c++latest 和 /permissive- 进行编译,并且希望保留它们。

我在这里错过了什么?

【问题讨论】:

    标签: c++ visual-c++


    【解决方案1】:

    [dcl.pre]/10

    static_assert 声明中,常量表达式根据上下文转换为 bool,转换后的表达式应为常量表达式 ([expr.const])。如果这样转换后表达式的值为true,则声明无效。否则,程序是病式的, 并且生成的诊断消息 ([intro.compliance]) 应该包括字符串文字的文本(如果提供的话)。

    通过将 false 放在您的 static_assert 中,您使程序格式错误,并且编译器在拒绝该程序时是正确的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多