【问题标题】:How to access template parameters from a derived class?如何从派生类访问模板参数?
【发布时间】:2012-08-08 20:54:03
【问题描述】:

我有一个

template <int N> class Base

class Derived : public Base<1>

...有没有办法从Derived::myMethod() 的定义中访问int N(而不是得到编译器错误“使用未声明的标识符'N'”)?

更准确地说,我想做

void Derived::myMethod() {
   for (int n=0; n<N; n++) { ...

【问题讨论】:

  • 为什么不直接写 1 而不是 N?你想做什么?
  • 似乎是个奇怪的问题,因为你知道 N 是 1。
  • 对,我知道 N==1。但是我会在Derived::myMethod() 中出现很多“1”,我想有一种更聪明的方法可以在开发过程中更改 N 的值,而不是手动将所有“1”更新为某个新值。

标签: c++ templates derived


【解决方案1】:

模板参数有模板的作用域,但是你可以在模板中定义一个可以被派生类使用的嵌套常量:

template <int N> class Base {
public: // or protected:
   static const int theN = N;
};

【讨论】:

  • 创意+1,但如果他需要这样做,我认为这更有可能是一个设计问题......
  • 我的猜测是它一个设计问题。我猜他已经创建了一个模板化的容器,并且正在使用它的继承(而不是组合),同时试图通过一些受保护的而不是公共的接口来访问容器。但是我的水晶球可能已经关闭了......
  • 当我的水晶球关闭时我讨厌它...... :(
  • @David:+1 谢谢,那会奏效。不过,这不是我所期望的——这通常不会为那个额外的 const 分配内存至少一次(即使它是一个静态变量,除非它被优化掉)?另外,从风格上讲,现在我已经复制了对这个值的访问(通过 N 和 theN),这不是极简主义的。
  • @David+Luchian:当然这可能是一个设计问题......但我想要实现的是:我有一个专门用于许多捕获设备的模板类,现在我想派生一个为 N=1 情况实现特殊操作的类。然而,这个派生类只是 N=1 模板的特化。
【解决方案2】:

另一种选择是您可以模板派生类:

template <int N>
class Derived : public Base<N>
{
    void myMethod()
    {
        for (int i = 0; i < N; ++i)
        //
    }
};

【讨论】:

  • 是的,但是对于 N!=1 ... 永远不会使用 Derived ... 所以这将对 Derived 的用户造成过度的负担(并且还会公开实现详细信息)以指定 每次实例化它。
  • 这就是我会做的事情(如果我最终出于某种原因需要以这种方式使用模板参数。对我来说 N 是模板化的,这对我来说似乎很奇怪。你真的需要有吗? N 的每个值的实例化(似乎这可能会导致严重的代码膨胀)。@PhilippJS 鉴于您对 Jesse 回答的评论,为什么模板需要 1。这不是在构造时初始化的成员吗?请参阅下面的答案...
  • @clanmjc:正如我在上面的评论中解释的那样,Base 代表一堆 N 个捕获设备。对于Derived,我在myMethod() 中只有一个需要特殊处理的捕获设备——但非常具体。我有一些从Base&lt;N&gt;::myMethod()Derived::myMethod() 的代码复制粘贴,但我想尽量减少结构更改以避免错误。重新“在构造时初始化的成员(我猜是Derived)”-再次,我必须在元素初始化列表中硬编码“Derived::myN(1)”,不是吗?
  • 请参阅下面关于硬编码的回答。此外,N 是字面意义上的 int,还是 N 某个对象。但是,您将其切块,包括在您的示例中,某处将有 1 个硬编码。然而,这并不意味着 Dervied 类需要知道任何关于这个细节的事情。
【解决方案3】:

这就是我上面评论的意思:

class Base{
  public:
     Base(int value = 1) : value_(value){}  //don't need to use default param but can
  private:
     int value_
}

class Derived : public Base
{}

为什么要模板化 N?你需要专攻整个班级吗?另一种方法是根据您设置为“专业化”的标准“虚拟化”从模板调用的非成员函数。

编辑:Partial specialization of a method in a templated class

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 2014-03-13
    相关资源
    最近更新 更多