简体   繁体   中英

Can a partial specialization refer to sizeof(T) in the specialization's argument list?

Look at this simple code ( godbolt ):

template <typename, int>
struct Foo;

template <typename T>
struct Foo<T, (int)sizeof(T)>;

Clang compiles it, while gcc doesn't:

error: template argument '(int)(sizeof (T))' involves template parameter(s)
    struct Foo<T, (int)sizeof(T)>;
                  ^~~~~~~~~~~~~~

Which compiler is correct and why?

According to 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) is not a simple identifier.

So gcc is right.

Possible work around, if appropriate, is to replace non-type template parameter by a type (wrapping the constant):

template <typename, typename Size>
struct Foo;

template <typename T>
struct Foo<T, std::integral_constant<int, (int)sizeof(T)>>;

Demo

More recent version temp.class.spec#match-3 (after CWG1315 ) allows it:

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 ]

So clang is right.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM