DEV Community

Discussion on: C++ Template Specialization - Syntax Note

Collapse
 
rogerzanoni profile image
Roger Zanoni

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

Collapse
 
deciduously profile image
Ben Lovy

Huh, interesting. Thanks!

Collapse
 
codemouse92 profile image
Jason C. McDonald

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.

Collapse
 
rogerzanoni profile image
Roger Zanoni

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"

Thread Thread
 
codemouse92 profile image
Jason C. McDonald

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.