1

I have the following code in the header file:

template<typename A, typename B>  class TemplateTest;

template<>
class TemplateTest<int, double>
{
public:
    float operator() (float a);
};

The definition in the cpp file:

template<>   // this is problematic line
float TemplateTest<int, double>::operator()(float a)
{
    float b;
    b = a + 5;
    return b;
}

with the "template<>" in the definition, MSVC returns error C2910 as it interprets operator() as a template method instead of a method of a template class. GCC behaves similar. But Solaris CC requires the "template<>" (otherwise it issues error ' "template<>" syntax is required when explicitly specializing a member of ...'.

So my question is which one is correct and how to make the code compile on all these platforms.

Jane2004
  • 31
  • 3
  • make sure to read this: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – bolov Oct 16 '17 at 23:04
  • @bolov That advice only applies to definitions that have at least one template parameter. This specialized `operator()` definition has none. – aschepler Oct 16 '17 at 23:50

2 Answers2

2

Solaris CC is incorrect. The template<> is not permitted. C++14 Standard [temp.expl.spec]/5:

Members of an explicitly specialized class template are defined in the same manner as members of normal classes, and not using the template<> syntax. ...

[ Example:

template<class T> struct A {
  struct B { };
  template<class U> struct C { };
};

template<> struct A<int> {
  void f(int);
};

void h() {
  A<int> a;
  a.f(16);    // A<int>::f must be defined somewhere
}

// template<> not used for a member of an
// explicitly specialized class template
void A<int>::f(int) { /*...*/ }

... - end example ]

It looks like to support Solaris CC, you will have to use something like:

#ifdef __SUNPRO_CC
template <>
#endif
float TemplateTest<int, double>::operator()(float a)
{
    float b;
    b = a + 5;
    return b;
}

If you have a lot of these, you may want to put that boilerplate into a custom macro.

Community
  • 1
  • 1
aschepler
  • 70,891
  • 9
  • 107
  • 161
0

You don't need

template<>   // this is problematic line

Full example:

template<typename A, typename B>  class TemplateTest;

template<>
class TemplateTest<int, double>
{
public:
    float operator() (float a);
};

float TemplateTest<int, double>::operator()(float a)
{
    return 0;
}

Wandbox

Look for "Members of specializations" in C++ Reference

Andriy Tylychko
  • 15,967
  • 6
  • 64
  • 112