看看这个简单的代码( godbolt ):
template <typename, int>
struct Foo;
template <typename T>
struct Foo<T, (int)sizeof(T)>;
Clang 会编译它,而 gcc 不会:
error: template argument '(int)(sizeof (T))' involves template parameter(s)
struct Foo<T, (int)sizeof(T)>;
^~~~~~~~~~~~~~
哪个编译器是正确的,为什么?
最佳答案
根据 https://timsong-cpp.github.io/cppwp/n4140/temp.class.spec#8.1
A partially specialized non-type argument expression shall not involve a template parameter of the partial specialization except when the argument expression is a simple identifier.
sizeof(T)
不是一个简单的标识符。所以 gcc 是对的。
如果合适,可能的解决方法是用类型替换非类型模板参数(包装常量):
template <typename, typename Size>
struct Foo;
template <typename T>
struct Foo<T, std::integral_constant<int, (int)sizeof(T)>>;
Demo
更新版本 temp.class.spec#match-3 (在 CWG1315 之后)允许它:
If the template arguments of a partial specialization cannot be deduced because of the structure of its template-parameter-list and the template-id, the program is ill-formed. [ Example:
template <int I, int J> struct A {}; template <int I> struct A<I+5, I*2> {}; // error template <int I> struct A<I, I> {}; // OK template <int I, int J, int K> struct B {}; template <int I> struct B<I, I*2, 2> {}; // OK
— end example ]
所以clang是对的。
关于c++ - 部分特化可以在特化的参数列表中引用 sizeof(T) 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61293683/