3
votes

How to specialise a templated constructor of a non-template class? The code below compiles fine with gcc and icc, but not with clang and msvc.

Is the code a) illegal but icc/gcc compiles it anyway or b) is legal but clang/msvc fail to compile for some reason.

Reproducer:

$ cat template_01.cpp
struct A
{
  template<class T>
  A(T const &t);
};

template<>
A::A<double>(double const& t) {}

int main()
{
  A a(42.0);
}

Reproducing steps:

$ clang++ template_01.cpp
template_01.cpp:8:4: error: qualified reference to 'A' is a constructor name rather than a type wherever a constructor can be declared
A::A<double>(double const& t) {}
   ^
template_01.cpp:8:5: error: expected unqualified-id
A::A<double>(double const& t) {}
    ^
2 errors generated.
$

$ g++ template_01.cpp
$

$ icc template_01.cpp
$

$ cl.exe template_01.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.40629 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

template_01.cpp
template_01.cpp(8) : error C2143: syntax error : missing ';' before '<'
template_01.cpp(8) : error C2988: unrecognizable template declaration/definition
template_01.cpp(8) : error C2059: syntax error : '<'
template_01.cpp(11) : error C2143: syntax error : missing ';' before '{'
template_01.cpp(11) : error C2447: '{' : missing function header (old-style formal list?)
$
2
Use simple overload. - Jarod42
Removing <double> fix compilation for clang Demo - Jarod42

2 Answers

3
votes

I believe, it is a bug in CLang. There is nothing in standard which prevents explicit specialization for constructors, and similar issue in gcc was considered to be a bug:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=9050

0
votes

I found here by searching, and the link T.C. mentioned has the final say (in 2019).

It is now determined that "template arguments shall not be specified" in the constructor template specialization. I.e. the following code is valid:

template<>
A::A(double const& t) {}

And I have verified that both GCC and Clang accept it now.