Alex Rivera | Logout

Why compiler doesn't give error while defining similar template specializations?

Asked 2012-06-21T06:19:38.620
10

What is the procedure of comparing the class template specializations? The standard is not detailed on this point (or I am missing the right place).
My question has NOTHING TO DO with deciding what specialization to use during the instantiation. Please, do not comment on that. The question is about comparing the specializations with each other to decide if particular specialization is already defined or not yet.

Consider this sample code:

template <class x1, class x2>
struct CoreTemplate { };

template <class x1, class x2>
struct CoreTemplate<x1*, x2*> { int spec; CoreTemplate() { spec = 1; } };

template <class x1, class x2>
struct CoreTemplate<x2*, x1*> { int spec; CoreTemplate() { spec = 2; } };

int main(int argc, char* argv[])
{
    CoreTemplate<int*, int*> qq;
    printf("var=%d.\r\n", qq.spec);
}

When I try to compile this code with MSVC, I get an error for the instantiation attempt inside the main function:

cpptest1.cxx(15) : error C2752: 'CoreTemplate<x1,x2>' : more than one partial specialization matches the template argument list

For me it would be more logical to issue an error for an attempt to declare identical template specializations. I do not see any difference between the specializations above.

So, does anybody know rules of comparing template specializations? Articles, links, books, etc will also help.

Edit
Report

1 Answer

0

For me it would be more logical to issue an error for an attempt to declare identical template specializations.

That would not happen, because CoreTemplate<int*, double*> and CoreTemplate<double*, int*> will generate different types.

Below is my guess:
Compiler may not do the extra sanity/common-sense checks for template bodies.
Once you instantiate a template, at that time compiler looks up for the matching type and picks up the best one. If it doesn't match only one, then it gives compiler error either for no-match or multiple-match.

For example:

template<typename T>
void foo ()
{
  T::x();
}

int main ()
{
}

Would compile fine, even though we know that in whole C++ program there is not a single function name x(). Compiler will give error only when you try instantiating the foo<T>.

Also if you twist your example a bit by putting main() between two specializations, it will compile perfectly fine.

answered 2012-06-21T06:26:16.793

Your Answer