0

我有一个这样的模板:

template<typename T>
struct foo {
  foo(T t) {
    //code
  }
  virtual double computation() = 0;
  //other members
};

我希望用户为他们自己的子类提供自定义Tcomputation()如下所示:

struct my_foo : public foo<std::string> {
  double computation() override { return 9.99; }
};

问题是这不起作用:

my_foo("hello");

我必须要求用户为每个子类创建一个新的构造函数,即使它所做的只是调用超类的构造函数。这看起来很傻。

您能否建议可能更适合我的替代“设计模式”?

4

2 回答 2

1

据我从您的示例中可以看出,您希望用户指定类型和计算函数。由于您没有提供虚拟析构函数,我假设您不想以多态方式使用生成的模板实例化,例如,您不想foo<string>在同一个地方存储/交换不同的实现。换句话说,纯虚函数的唯一目的似乎是让computation()客户端强制执行。

您还希望模板的构造函数可以使用,而客户端不必重新实现或显式将其导入到他的类中。my_foo只有当它是派生类的实例foo而不是派生类时才能实现。

在这种情况下,您可以使用基于策略的设计:

template<typename T, typename ComputationPolicy>
struct foo : ComputationPolicy {
  foo(T t) {
    //code
  }

  void bar() {
    double d = ComputationPolicy::computation(); //just use it!
  }

  //...
};

模板的用户现在必须定义一个具有 function 的类型computation(),返回一个可转换为 double 的值,否则无法实例化模板:

struct myComp  {
  double computation() { return 9.99; }
};

typedef foo<std::string, myComp> my_foo;

my_foo("hello");
于 2013-06-18T06:21:21.530 回答
1

我相信它与模板没有直接关系。

这仅仅是因为:在 C++ 中,构造函数不是继承的。

试试这个例子,你会发现它不起作用:

class Parent {
public:
    Parent(int i) {
        cout << "i " << i << endl;
    };
};

class Child : public Parent {
};

int main(int argc, char** args) {
    Child child(1);
    return 0;
}

因为默认情况下,Child 的构造函数将调用 Parent 的无参数 ctor。然而,无参数 ctor 在 Parent 中不可用。

更改 Child 以提供适当的 ctor 将解决问题:

class Child : public Parent {
public:
    Child(int i):Parent(i) {
    }
};

在这个例子中,我为 Child 创建了一个带有 1 个参数的 ctor。此子 ctor 将调用父级的Parent(int)ctor。

在您的问题中,您说要求 Child 类创建 ctor 很愚蠢:这根本不傻!您永远不会知道孩子希望如何实例化其类。某些子类可能仅合理地根据其语义含义为 ctor 使用 2 个参数构造。

如果您真的希望它神奇地完成,您可以做的一种最简单的方法是创建宏来“生成”子类的类声明和相应的 ctor。然而,这样做很少有意义。

于 2013-06-18T07:59:15.993 回答