C++ 模板专门化中的静态断言即使未实例化也会失败

C++ 模板专门化中的静态断言即使未实例化也会失败,c++,language-lawyer,template-specialization,static-assert,C++,Language Lawyer,Template Specialization,Static Assert,以下代码编译得很好: #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(depend

以下代码编译得很好:

#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;
}
然后,模板专门化中的静态断言失败,即使它没有实例化我只是想知道为什么。我在GCC 8和Clang 6中观察到了这种行为(
-std=c++17


实况演示:

< P>甚至非实例化的模板部分应该是有效的C++代码。代码>静态断言(false)使程序格式错误。因此,您需要专门处理
static\u assert
,这在编译时被认为是
false
,并且您的程序会变得格式错误。您的类中没有未解析的模板参数,这些参数在
static\u assert
中使用,使编译器感到惊奇;它确切地知道它是
false

同样,如果constexpr,您也不能对已知为false的表达式使用
static\u assert
,即使该
static\u assert
所在的部分总是被丢弃-不再是模板

显式专用类的成员不是隐式的 从类模板的成员声明实例化; 相反,类模板专门化的成员应该自己 如果需要其定义,则应明确定义。在这种情况下 类模板显式专门化的定义应在 定义成员的点处的范围的定义 显式专用类与 生成专门化。也就是说,其成员不必拥有相同的权限 作为生成的专门化的成员的名称、类型等。 显式专用类模板的成员在 与普通类成员的方式相同,并且不使用模板 语法。当显式定义 专业会员班。但是,模板用于定义 显式专用成员类模板的成员,该模板是 专门化为类模板

专业化就像一个普通的类。它不是一个模板,没有任何东西是依赖的。因此,
dependent_false::value
只是一个常量表达式,其计算结果立即为false。因此,会立即触发静态断言

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;
}