这是一个简短的独立测试用例来解释我的问题.GCC接受此代码,但clang和Intel拒绝它:
template <typename T>
struct false_t {
static const bool value = false;
};
template <typename T>
int f() {
static_assert(false_t<T>::value, "");
return 0;
}
template <typename T>
struct S {
int m = f<T>();
};
int s = sizeof(S<int>);
Run Code Online (Sandbox Code Playgroud)
或者,根据pmr的评论,这里有一个更简单的例子,它也被gcc接受并被clang拒绝:
struct S;
template <typename T> struct X { int x = T(); };
int s = sizeof(X<S>);
Run Code Online (Sandbox Code Playgroud)
sizeof(S<int>)(或sizeof(X<S>))应该实例化它需要的类的位,但编译器不同意这些位是什么.由于非静态数据成员初始值设定项仅由构造函数使用,因此GCC将实例化作为实例化类的构造函数的一部分.clang和英特尔早些时候这么做了.
我无法理解[temp.inst] p1中标准的含义:
类模板特化的隐式实例化导致类成员函数,成员类,作用域成员枚举,静态数据成员和成员模板的声明的隐式实例化,而不是定义或默认参数的隐式实例化.它会导致隐式实例化未作用域成员枚举和成员匿名联合的定义.
因为我根本没有看到非静态数据成员(有或没有初始化)的声明在哪里被实例化.
关于我在哪里遇到这个的更多细节:我试图创建一个模板助手类(它永远不会在运行时创建),其中包含一个使用初始化的成员std::declval<T>()(我应该添加,我现在意识到它没什么用处)无论如何),libstdc ++的实现std::declval包含一个静态断言,就像我的例子中的断言一样.我可以通过避免而不费力地解决问题std::declval,但我想知道标准需要什么.