代码之家  ›  专栏  ›  技术社区  ›  Daniel Langr

即使没有实例化,模板专门化中的静态断言也会失败

  •  3
  • Daniel Langr  · 技术社区  · 6 年前

    以下代码编译得很好:

    #include <type_traits>
    
    template <typename T> struct dependent_true : std::true_type { };
    template <typename T> struct dependent_false : std::false_type { };
    
    template <bool B = false>
    class X { static_assert(dependent_false<X>::value); };
    
    template <>
    class X<true> { static_assert(dependent_true<X>::value); };
    
    int main() {
       X<true> x;
    }
    

    static_assert 在主模板中不计算。相反,如果我切换到:

    template <bool B = false>
    class X { static_assert(dependent_true<X>::value); };
    
    template <>
    class X<true> { static_assert(dependent_false<X>::value); };
    
    int main() {
        X<false> x;
    }
    

    然后,模板专门化中的静态断言失败,即使它没有实例化。 我只是想知道为什么。 我在gcc8和clang6中观察到了这种行为( -std=c++17 ).

    https://wandbox.org/permlink/MOWNLnGMgmuDA2Ht

    2 回复  |  直到 6 年前
        1
  •  6
  •   StoryTeller - Unslander Monica    6 年前

    template <> class X<true> {/* ... */}; -不再是模板。

    [temp.expl.spec]/5

    显式专用化类的成员不是隐式的 从类模板的成员声明实例化; 如果需要它的定义,则可以显式定义。在这种情况下 定义成员的点的范围。 定义 生成专门化 . 也就是说,其成员不必拥有相同的权利 作为生成的专门化的成员的名称、类型等。 与普通类成员的方式相同,并且不使用模板<gt; 语法。 当显式定义 显式专用成员类模板的成员 专门用作类模板。

    专业化就像一个普通的班级。它不是一个模板,没有什么是依赖的。因此 dependent_false<X>::value 只是一个立即计算为false的常量表达式。因此,会立即触发静态断言。

        2
  •  0
  •   ixSci    6 年前

    static_assert(false) 使程序格式错误。所以你有自己的专长 static_assert 在编译时已知 false 你的程序会变得不正常。在中使用的类上没有未解析的模板参数 使编译器感到惊奇;它确切地知道它是

    这同样适用于 if constexpr ,您也不能使用 静态\u断言 总是被丢弃。