Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial specialization with type nested in a templated class

I'm playing with templates and partial specialization, but there is one specialization I don't know how to write... I'll simplify code to make it easier to read.

Let's condiser

template <typename T>
    class x
{
    ...
};

Usually, I can specialize like this :

class x<a_type>
{
    ...
};

Also works with templates types :

template <typename T>
    class x<std::vector<T>>
{
    ...
}

Now I would like to make the specialization for a type nested in a templated class:

template <typename T>
    class y
{
    struct nested_type
    {
        y a_member;
    };

    ...
};

// Here comes the specialization

template <typename T>
    class x<y<T>::nested_type>
{
    ...
};

This fails. I also tried to put 'typename' before y::nested_type but it did not solved the problem. Compiler error is:

type/value mismatch at argument 1 in template parameter list for ‘template <class T> struct x’

What I want to do seems logical, but I'm not sure if it is possible. I'm using C++0x with g++-4.5. Does anybody know the correct syntax to write such specialization ?

like image 930
neodelphi Avatar asked May 24 '11 17:05

neodelphi


People also ask

Can you partially specialize a C++ function template?

You can choose to specialize only some of the parameters of a class template. This is known as partial specialization. Note that function templates cannot be partially specialized; use overloading to achieve the same effect.

What is a templated class in C++?

Definition. As per the standard definition, a template class in C++ is a class that allows the programmer to operate with generic data types. This allows the class to be used on many different data types as per the requirements without the need of being re-written for each type.

Can a non templated class have a templated member function?

A non-template class can have template member functions, if required. Notice the syntax. Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class.

Which entities can be templated C++?

A templated entity (or, in some sources, "temploid") is any entity that is defined (or, for a lambda-expression, created) within a template definition. All of the following are templated entities: a class/function/variable (since C++14) template.


1 Answers

The answer is that you cannot do this specialization. It is not a syntax error, but just something that cannot be realized. You have to see template specializations a little bit like function overloading. The compiler has to take the type argument at the use-site, look at the specializations available, find matches, and select the best one (most specialized one). The problem with your example is that the "find match" step cannot be realized with such a specialization. The compiler can expect "nested_type" to be anything, not necessarily a unique type (as it is in your example), it could also be a nested typedef, for instance. Moreover, the compiler cannot predict that it is already seeing all the specializations of template "y", so even if nested_type is a unique type nested in y (general template), it could be a nested typedef in an upcoming template specialization declaration for template "y".

Just like with function overloading and the matching algorithm used there, the compiler is limited in its capabilities to deduce the type, and what limits it is how much assumptions it can make. If you have a specialization for x<int> and later use x<int>, the match is trivial, no deduction needed, no assumptions needed. If you have a specialization like x<T*> and later use x<int*>, the match is easy, T can be deduced to be int. If you have a specialization like x< y<T>::type > and then use any version of x, how is the compiler supposed to deduce T from y::type? It would have to substitute for T in y all the possible types that exist in the entire world to see if there is one that results in a matching nested type. That's an unreasonable expectation, and that is why the type deduction capabilities of C++ templates stop here. Very often, to know if you should expect the compiler to be able to resolve something, just put yourself in its shoes and see if it is even remotely possible (the answer is usually clear).

like image 199
Mikael Persson Avatar answered Sep 28 '22 01:09

Mikael Persson