Thanks for the insight, Roger. It's odd that this form of specialization, just limiting the valid argument types for a generic function, is not documented very well...or, really, at all as far as I can tell.
Hello Jason, I forgot to post two bits of documentation I saved in my first reply:
14.7.3/2:
An explicit specialization shall be declared in a namespace enclosing the specialized template. An explicit specialization whose declarator-id is not qualified shall be declared in the nearest enclosing namespace of the template, or, if the namespace is inline (7.3.1), any namespace from its enclosing namespace set. Such a declaration may also be a definition. If the declaration is not a definition, the specialization may be defined later (7.3.1.2).
7.1.1/1:
At most one storage-class-specifier shall appear in a given decl-specifier-seq, except that thread_local
may appear with static or extern. If thread_local appears in any declaration of a variable it shall be
present in all declarations of that entity. If a storage-class-specifier appears in a decl-specifier-seq, there
can be no typedef specifier in the same decl-specifier-seq and the init-declarator-list of the declaration shall
not be empty (except for an anonymous union declared in a named namespace or in the global namespace,
which shall be declared static (9.5)). The storage-class-specifier applies to the name declared by each
init-declarator in the list and not to any names declared by other specifiers. A storage-class-specifier shall
not be specified in an explicit specialization (14.7.3) or an explicit instantiation (14.7.2) directive.
This code
class idksomefunctions {
public:
idksomefunctions() = delete; // specify there should be no constructor
template <typename T>
static T myIdentityFunction(T val)
{
return val;
}
template static int myIdentityFunction(int val);
};
looks ok according to the first bit, but if I got it correctly, it fails because of this rule from the second one "A storage-class-specifier shall not be specified in an explicit specialization"
Makes total sense. I've always done this sort of specialization in the .cpp file, but the transition to header-only on this library has forced me to consider some of the deeper technical implications.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Hello!
It works if you define it it outside class scope: godbolt.org/z/mL7JsO
I tried to find a reason in the standard for it to work like this but didn't find anything
Huh, interesting. Thanks!
Thanks for the insight, Roger. It's odd that this form of specialization, just limiting the valid argument types for a generic function, is not documented very well...or, really, at all as far as I can tell.
Hello Jason, I forgot to post two bits of documentation I saved in my first reply:
14.7.3/2:
An explicit specialization shall be declared in a namespace enclosing the specialized template. An explicit specialization whose declarator-id is not qualified shall be declared in the nearest enclosing namespace of the template, or, if the namespace is inline (7.3.1), any namespace from its enclosing namespace set. Such a declaration may also be a definition. If the declaration is not a definition, the specialization may be defined later (7.3.1.2).
7.1.1/1:
At most one storage-class-specifier shall appear in a given decl-specifier-seq, except that thread_local
may appear with static or extern. If thread_local appears in any declaration of a variable it shall be
present in all declarations of that entity. If a storage-class-specifier appears in a decl-specifier-seq, there
can be no typedef specifier in the same decl-specifier-seq and the init-declarator-list of the declaration shall
not be empty (except for an anonymous union declared in a named namespace or in the global namespace,
which shall be declared static (9.5)). The storage-class-specifier applies to the name declared by each
init-declarator in the list and not to any names declared by other specifiers. A storage-class-specifier shall
not be specified in an explicit specialization (14.7.3) or an explicit instantiation (14.7.2) directive.
This code
looks ok according to the first bit, but if I got it correctly, it fails because of this rule from the second one "A storage-class-specifier shall not be specified in an explicit specialization"
Delicious spec quotes. :)
Makes total sense. I've always done this sort of specialization in the
.cpp
file, but the transition to header-only on this library has forced me to consider some of the deeper technical implications.