Home > Blockchain >  What `foo.template bar()` should do when there's both a template and a non-template overload?
What `foo.template bar()` should do when there's both a template and a non-template overload?

Time:01-09

A coworker shared this code with me:

void foo() {std::cout << "2\n";} }; int main() { A x; x.template foo(); }'),l:'5',n:'0',o:'C++ source #1',t:'0')),k:43.28981723237598,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:clang1300,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:2,lang:c++,libs:!(),options:'-std=c++20 -Wall -Wextra -pedantic-errors',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1,tree:'1'),l:'5',n:'0',o:'x86-64 clang 13.0.0 (C++, Editor #1, Compiler #2)',t:'0')),header:(),k:29.623619985624018,l:'4',m:49.21700223713646,n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compiler:2,editor:1,fontScale:14,fontUsePx:'0',tree:'1',wrap:'1'),l:'5',n:'0',o:'Output of x86-64 clang 13.0.0 (Compiler #2)',t:'0')),header:(),l:'4',m:50.78299776286354,n:'0',o:'',s:0,t:'0')),k:56.71018276762404,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4" rel="noreferrer">run on gcc.godbolt.org

#include <iostream>

struct A
{
    void foo() {std::cout << "1\n";}
    
    template <typename T = int>
    void foo() {std::cout << "2\n";}
};

int main()
{
    A x;
    x.template foo();
}

GCC prints 1, Clang prints 2, and MSVC complains about missing template arguments.

Which compiler is correct?

CodePudding user response:

MSVC is correct to reject this: the standard has just this as an example. The template parser guide is allowed before the qualified name of a class or alias template without template arguments, but this is only for compatibility with implementations that needlessly require it for template template arguments and is now deprecated.

CodePudding user response:

[temp.names]/5 says that a name prefixed by template must be a template-id (or refer to a class/alias template), meaning that it must have a template argument list.

There is even an example almost identical to yours under it, identifying your use of template as ill-formed.

Open GCC bug report for this is here.

  •  Tags:  
  • Related