【问题标题】:Inheriting with default template parameter of nested class within template outer class继承模板外部类中嵌套类的默认模板参数
【发布时间】:2017-05-24 13:00:49
【问题描述】:

我有一个模板外部类(下面的Outer)和一个公共模板嵌套类(Inner)。 Inner 的模板参数有一个默认值。我专门OuterSpecializedOuter),然后从嵌套类(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&lt;void&gt;: SpecializedOuter::Inner&lt;void&gt; 中删除 &lt;void&gt;,则会出现编译错误。我希望编译器会使用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"
  {}
};

用例

如果您想知道,在我的用例中,OuterOpenSceneGraph's osg::Geometry 的子类,Innerosg::Drawable::UpdateCallback 的子类。为了方便起见,我正在尝试将样板移动到Inner,并消除对dynamic_castosg::GeometryOuter&lt;T&gt; 的需要。

【问题讨论】:

    标签: class c++11 templates inheritance default-value


    【解决方案1】:

    好吧,发布后我在this question 找到了答案。我会把它留在这里,以防它对其他人有用。使用默认值时,您仍然必须将&lt;&gt; 放在类名的末尾,以将其从模板名称转换为实例化类的名称(根据this answer 上述问题)。这样编译成功:

    template<typename T>
    class Outer {
    public:
      template<typename U = void>
      class Inner {
        Outer *outer_;
      public:
        Inner(Outer *outer): outer_(outer) {}
      };
    }; //Outer
    
    typedef Outer<int> SpecializedOuter;
    
    class SpecializedInner: public SpecializedOuter::Inner<> { 
        // without <void>, but with <> => OK
    public:
      SpecializedInner(SpecializedOuter *so)
        : Inner<>(so)     // without <void>, with <> => OK.  Plus, don't have to
      {}                  // re-specify `SpecializedOuter::`!
    };
    // vi: set ts=2 sts=2 sw=2 et ai: //
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-04
      • 1970-01-01
      • 2018-11-26
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多