Search code examples
c++templatesauto

Meaning of template<auto = {}>


What type and default value does the single template parameter have in the following code?

template<auto = {}>
int getInt();

Clang with -Xclang -ast-dump only says:

| |-NonTypeTemplateParmDecl 0xcb77130 <line:1:10, col:18> col:15 'auto' depth 0 index 0
| | `-TemplateArgument expr
| |   `-InitListExpr 0xcb77050 <col:17, col:18> 'void'

Solution

  • Consider this template:

    template<int = "">
    int getInt();
    

    It compiles successfully, but the default value can't actually be used:

    int main() {
        getInt();
    }
    
    <source>:5:5: error: no matching function for call to 'getInt'
        5 |     getInt();
          |     ^~~~~~
    <source>:2:5: note: candidate template ignored: substitution failure: value of type 'const char[1]' is not implicitly convertible to 'int'
        1 | template<int = "">
          |                ~~
        2 | int getInt();
          |     ^
    

    You have to explicitly call it with a value, like getInt<0>();

    It's the same with template<auto = {}>: A default value is provided, but the type can't be deduced from the initializer, so getInt() can't call that function template. You can only ever use getInt<(initializer)>{}.


    If you're wondering what auto means, it's a placeholder type. It's not deduced from the default, it's deduced from the initializer in the call (which may be the default if nothing is provided or otherwise deduced).

    So this is perfectly valid:

    template<auto = 0>
    int getInt();
    
    char x;
    int main() {
        getInt();  // Type of the first NTTP is `int`, deduced from `0`.
        getInt<&x>();  // Type of the first NTTP is `char*`, deduced from `&x`. Default is not used.
    }