【发布时间】:2017-05-24 13:00:49
【问题描述】:
我有一个模板外部类(下面的Outer)和一个公共模板嵌套类(Inner)。 Inner 的模板参数有一个默认值。我专门Outer(SpecializedOuter),然后从嵌套类(SpecializedOuter::Inner)派生来定义一个新类(SpecializedInner)。如果我在SpecializedInner 的定义中指定Inner 的模板参数,编译就可以了。但是,如果我在 SpecializedInner 中省略了 Inner 的模板参数,即使指定了默认值 (Inner<U=void>),g++ 也不会编译代码。
有什么方法可以为 g++ 和 VS2013 解决这个问题吗?我查看了 Google 搜索结果和其他问题,但无法找到将“默认”和“模板”的所有可能用途区分开来的搜索词:)。
代码和错误信息
以下test.cpp 在 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
{}
};
但是,如果我从 public SpecializedOuter::Inner<void> 和 : SpecializedOuter::Inner<void> 中删除 <void>,则会出现编译错误。我希望编译器会使用Inner 定义中的默认typename U = void。代码和错误是:
// ... 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"
{}
};
用例
如果您想知道,在我的用例中,Outer 是 OpenSceneGraph's osg::Geometry 的子类,Inner 是 osg::Drawable::UpdateCallback 的子类。为了方便起见,我正在尝试将样板移动到Inner,并消除对dynamic_cast 从osg::Geometry 到Outer<T> 的需要。
【问题讨论】:
标签: class c++11 templates inheritance default-value