I have a template outer class (Outer
below) with a public template nested class (Inner
). The template parameter of Inner
has a default. I specialize Outer
(SpecializedOuter
), then derive from the nested class (SpecializedOuter::Inner
) to define a new class (SpecializedInner
). Compilation is fine if I specify Inner
's template parameter in the definition of SpecializedInner
. However, g++ won't compile the code if I omit Inner
's template parameter in SpecializedInner
, even though a default is specified (Inner<U=void>
).
Is there any way to fix this for both g++ and VS2013? I have looked through Google results and other questions but am having trouble getting search terms that will distinguish all of the possible uses of "default" and "template" from each other :) .
Code and error messages
The following test.cpp
compiles with no errors or warnings on g++ 5.4.0, g++ -std=c++11 -Wall -c test.cpp -o test.o
:
template<typename T>
class Outer {
public:
template<typename U = void> // The default I want to take advantage of
class Inner {
Outer *outer_;
public:
Inner(Outer *outer): outer_(outer) {}
};
}; //Outer
typedef Outer<int> SpecializedOuter;
class SpecializedInner: public SpecializedOuter::Inner<void> {
// also works with int or double instead of void - I just have to specify some type.
public:
SpecializedInner(SpecializedOuter *so)
: SpecializedOuter::Inner<void>(so) // type also expressly specified here
{}
};
However, if I remove <void>
from public SpecializedOuter::Inner<void>
and : SpecializedOuter::Inner<void>
, I get compilation errors. I would expect that the compiler would use the default typename U = void
from the definition of Inner
. Code and errors are:
// ... definitions of Outer, Inner, SpecializedOuter as above ...
class SpecializedInner: public SpecializedOuter::Inner { // without <void>
// => "expected class-name before `{' token"
public:
SpecializedInner(SpecializedOuter *so)
: SpecializedOuter::Inner(so) // without <void>
// => "expected class-name before `(' token"
// => "expected `{' before `(' token"
{}
};
Use case
In case you are wondering, in my use case, Outer
is a subclass of OpenSceneGraph's osg::Geometry
and Inner
is a subclass of osg::Drawable::UpdateCallback
. I am trying to move boilerplate into Inner
for convenience, and remove the need for a dynamic_cast
from osg::Geometry
to Outer<T>
.
Aucun commentaire:
Enregistrer un commentaire