Redefining nested class on class specialization.

B

Belebele

The following code fails to compile. My intention is to provide
different definitions for a nested class for a class template partial
specialization. Here it is:


template <typename , int > class Outer {
public:
class Inner;
};

template <int i> class Outer<int, i>::Inner {};

template <int i> class Outer<double, i>::Inner {};



Do you have any idea why?

Thanks.
 
V

Victor Bazarov

Belebele said:
The following code fails to compile. My intention is to provide
different definitions for a nested class for a class template partial
specialization. Here it is:


template <typename , int > class Outer {
public:
class Inner;
};

template <int i> class Outer<int, i>::Inner {};

template <int i> class Outer<double, i>::Inner {};



Do you have any idea why?

The rule is, "you cannot specialise the member of a class template
without first specialising the template".

V
 
B

Belebele

The rule is, "you cannot specialise the member of a class template
without first specialising the template".

Don't quite get it. I am able to specialize a member function without
specializing the entire class template. The code below compiles OK:

template <typename > struct F {
void f();
};

template <>
void F<int>::f() {};

template <>
void F<double>::f() {};


I thought I could do the same with an inner class. If not, I would use
some indirection to achieve the effect I want. Redefining the inner
class would have been more direct.
 
V

Victor Bazarov

Belebele said:
Don't quite get it. I am able to specialize a member function without
specializing the entire class template. The code below compiles OK:

template <typename > struct F {
void f();
};

template <>
void F<int>::f() {};

template <>
void F<double>::f() {};


I thought I could do the same with an inner class. If not, I would use
some indirection to achieve the effect I want. Redefining the inner
class would have been more direct.

I believe you're confusing full specialisation with partial. A full
specialisation is *not* a template. A partial specialisation is still
a template. Try specialising your F::f for, say, all pointers.

V
 
B

Belebele

I believe you're confusing full specialisation with partial. A full
specialisation is *not* a template. A partial specialisation is still
a template. Try specialising your F::f for, say, all pointers.


Now I get it. I was mixing them up. Thanks.
 
A

Andrey Tarasevich

Victor said:
...
I believe you're confusing full specialisation with partial. A full
specialisation is *not* a template. A partial specialisation is still
a template. Try specialising your F::f for, say, all pointers.
...

Well, it is perfectly possible to specialize 'F::f' for all pointers
(referring to the parameter of the enclosing class template). The
question is whether it will work without providing a definition for the
outer class template, which is what the OP's question is really about. I
believe that in C++ this is simply not allowed. It is OK for explicit
specialization, but not allowed for partial specialization.

In order to make the original code compile th OP'd have to "re-declare"
the partially specialized outer classes

template <typename , int > class Outer {
public:
class Inner;
};

template <int i> class Outer<int, i> {
public:
class Inner;
};

template <int i> class Outer<int, i>::Inner {};

template <int i> class Outer<double, i> {
public:
class Inner;
};

template <int i> class Outer<double, i>::Inner {};

The above will compile. I don't now right away whether what appears as
"repetitive" declaration of 'Outer' can be avoided somehow.
 
V

Victor Bazarov

Andrey said:
Well, it is perfectly possible to specialize 'F::f' for all pointers
(referring to the parameter of the enclosing class template). The
question is whether it will work without providing a definition for
the outer class template, which is what the OP's question is really
about. I believe that in C++ this is simply not allowed. It is OK for
explicit specialization, but not allowed for partial specialization.

In order to make the original code compile th OP'd have to
"re-declare" the partially specialized outer classes

template <typename , int > class Outer {
public:
class Inner;
};

template <int i> class Outer<int, i> {
public:
class Inner;
};

template <int i> class Outer<int, i>::Inner {};

template <int i> class Outer<double, i> {
public:
class Inner;
};

template <int i> class Outer<double, i>::Inner {};

The above will compile. I don't now right away whether what appears as
"repetitive" declaration of 'Outer' can be avoided somehow.

The problem is, most likely, that the OP wanted the rest of the "outer"
template to remain intact and only provide the "custom" implementation
of the inner class ('Inner') for a particular [partial] specialisation
of the 'Outer'. That's what seems impossible (prohibited). One would
need to make copies of all original implementation when defining the
partial specialisation of 'Outer' (to keep it intact), or reimplement
it all using containment or private inheritance, to reuse the code...

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top