Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Templated class specialization where template argument is templated: difference Visual Studio vs. g++

The following code, which I derived reading this, compiles and behaves fine in gcc (link), but in Visual Studio gives an error.

Error C2910 'my_property<A<U>>': cannot be explicitly specialized

It works fine only if I remove the template <> line. I got the workaround here. The workaround version is ok also in g++.

#include <iostream>
#include <type_traits>

template <typename T>
struct A {
  T x;
};

template <typename T>
struct my_property {
  static const bool value = false;
};

template <> //Remove this and it will work in Visual Studio
template <typename U>
struct my_property<A<U>> {
  static const bool value = true;
};

int main() 
{
  std::cout << std::boolalpha;
  std::cout << my_property<int>::value << '\n'; //false
  std::cout << my_property<A<int>>::value << '\n'; //true
  std::cout << my_property<A<float>>::value << '\n'; //true
}

Which compiler is right?

like image 596
Antonio Avatar asked Oct 28 '22 16:10

Antonio


1 Answers

If I read the standard correctly, template<> should not be used in this case.

Basically, you have to provide multiple template parameter lists for nested templates:

(see [temp.mem] §1)

A template can be declared within a class or class template; such a template is called a member template. A member template can be defined within or outside its class definition or class template definition. A member template of a class template that is defined outside of its class template definition shall be specified with the template-parameters of the class template followed by the template-parameters of the member template.

...but you don't need to provide an additional template parameter list for specializing a template with a template parameter:

(see [temp.class.spec] §2)

Each class template partial specialization is a distinct template...

(and then §4)

The template parameters are specified in the angle bracket enclosed list that immediately follows the keyword template. For partial specializations, the template argument list is explicitly written immediately following the class template name. For primary templates, this list is implicitly described by the template parameter list...

There's nothing to suggest that an additional template parameter list is required - a specialization is just a template, and as such it requires just a single parameter list.

like image 135
shakurov Avatar answered Nov 15 '22 07:11

shakurov