0

I have a trouble with code below:

template<typename Name>
class Person;

template<typename Name, typename FamilyNmae>
class Person {};

template<typename Name, typename FamilyName>
class Person < Name(FamilyName) >
{
public:
   Person(Name a)
      : k{ a }
   {

   }

private:
   Name k;
   FamilyName l;
};

This code does not compile (C2977 'Person': too many template arguments), but if I do next:

template<typename Name>
class Person;

//template<typename Name, typename FamilyNmae>
//class Person {};

template<typename Name, typename FamilyName>
class Person < Name(FamilyName) >
{
public:
   Person(Name a)
      : k{ a }
   {

   }

private:
   Name k;
   FamilyName l;
};

It compiles properly. But I cannot find rule according which received the error. I mean not explanation from compiler writer, but from the standard. Does anybody know something about it ?

Denis Kotov
  • 857
  • 2
  • 10
  • 29
  • What `class Person < Name(FamilyName) >` means for you? – Ripi2 Jan 15 '17 at 23:47
  • It is just pattern to check how Types was put to the template instantiation: Person person(std::string("Denis")); – Denis Kotov Jan 15 '17 at 23:58
  • Not the standard, but interesting: http://stackoverflow.com/questions/11968994/why-is-it-not-possible-to-overload-class-templates – Ripi2 Jan 16 '17 at 00:54
  • I think that those two commented lines are not a specialization, they don't specialize anything. So they are taken as a redeclaration of class Person. Classes can't be overloaded, only functions can. – Ripi2 Jan 16 '17 at 01:18
  • @Ripi2 Thank you you are right – Denis Kotov Jan 17 '17 at 22:38

1 Answers1

0

In the latest publicly available draft, see 14.0.0.5 (shown below) and 14.5.5.

A class template shall not have the same name as any other template, class, function, variable, enumeration, enumerator, namespace, or type in the same scope (3.3), except as specified in (14.5.5).

It is not so explicit in regard to what exactly you are asking, but the 'except' clause is the critical part. It implies 'overloading' class templates cannot be done.

If you follow the reference to 14.5.5, you can see that what you want to do can only be done through template specialization.

Using 14.5.5.3 as a guide in how to properly specialize class templates, you could do something like this:

class EmptyName {}; //just a placeholder

template<typename Name, typename FamilyName>
class Person {};

template<typename Name>
class Person<Name, EmptyName> {};

Notice how the template declaration with 2 parameters is defined first as the "primary template" that you will specialize afterwards.

diametralpitch
  • 675
  • 3
  • 5
  • Thank you for answer I understood that it happened only due to overloading. Compiler tried to applied parameters to a new specialization, but specialization had not received any parameters in. – Denis Kotov Jan 17 '17 at 22:38