c++ - 如果没有 if-constexpr 成功,触发编译时错误的最佳方法?

标签 c++ typetraits static-assert if-constexpr

我有一长串 if constexpr 语句,如果它们都不成功,我想触发一个编译时错误。

具体来说,我有一个抽象语法树,我想将其结果转换为我可能需要的一组特定类型。我有 AsInt()、AsDouble() 等在工作,但我需要能够根据提供的类型更动态地执行此操作。

就目前而言,我已经编写了一个模板化的 As() 成员函数,但它的错误检查很笨拙。具体来说,使用静态断言需要一个笨重的测试条件。这是一个简化版本:

template <typename T>
T As() {
  if constexpr (std::is_same_v<T,int>) return AsInt();
  if constexpr (std::is_same_v<T,double>) return AsDouble();
  ...
  if constexpr (std::is_same_v<T,std::string>) return AsString();

  static_assert( std::is_same_v<T,int>
                 || std::is_same_v<T,double>
                 || ...
                 || std::is_same_v<T,std::string>,
                 "Invalid template type for As()" );
}

如果所有条件都失败,是否有更简单的方法来触发静态断言(或等效断言)?

最佳答案

您需要重写 if constexpr 的序列s 作为 if constexpr ... else if constexpr ... 的链并得到最后的 else如果“达到”(即未丢弃)子句会触发编译错误。这可以使用“依赖 false 成语”来完成:

if constexpr (std::is_same_v<T,int>) {
    return AsInt();
} else if constexpr (std::is_same_v<T,double>) {
    return AsDouble();
} ... else if constexpr (std::is_same_v<T,std::string>) {
    return AsString();
} else {
    // this is still constexpr, so it will be discarded if any other branch was taken
    static_assert(dependent_false<T>::value, "invalid template type for As()");
}

哪里dependent_false定义为:

template <class T> struct dependent_false : std::false_type {};

关于c++ - 如果没有 if-constexpr 成功,触发编译时错误的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69501472/

相关文章:

C++:在 OpenGL 中绘制 2D 磁盘

c++ - 带模板的类声明

c++ - cv-qualified struct 的成员不是类似的 cv-qualified

c++ - 在编译时比较静态字段指针

c++:交换 vector 和指针失效?

c++ - 如何使用模板创建带有斐波那契数的编译时模板化集/数组/vector ?

c++ - 带有成员函数指针的部分模板类特化

c++ - 使用 C++11 type_traits 了解 Microsoft 的 _Is_duration

c++ - 在 constexpr-if 条件下比较 constexpr 函数参数导致错误

c++ - ‘<temporary>’ 的修饰不是常量表达式