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