【问题标题】:Constructor inheritance in templated class (C++11)模板类中的构造函数继承 (C++11)
【发布时间】:2013-09-04 08:27:19
【问题描述】:

我有以下类定义:

template<typename T>
class Point {
  private:
    T px, py;
  public:
    Point(T x, T y): px(x), py(y) {
      std::cout << "created " << x << ":" << y <<std::endl;
    };
    T x() const { return px; };
    T y() const { return py; };
};

我从中派生的专业,例如

class PointScreen: public Point<int> {
  using Point::Point;
};

当我在clang++ 中编译它时,我没有收到警告/错误,但没有调用构造函数:

#include <iostream>
// definitions from above      
int main() {
  std::cout << PointScreen(100, 100).x() << std::endl;
  return 0;
}

这会返回一个随机值(也不是调试输出“created...”)。例如返回的值x() 显然是“未定义”。

我刚刚在g++here 中尝试了相同的方法,并获得了预期的结果。这是clang++ 的问题还是我的代码中有错误?

我的 clang 版本:Ubuntu clang 版本 3.0-6ubuntu3 (tags/RELEASE_30/final)(基于 LLVM 3.0)。我用-std=c++11 -Wall编译。

【问题讨论】:

  • 适用于 clang++3.4。 Live example
  • 继承ctors已经实现in clang 3.3
  • 有没有办法让这段代码在 clang 3.0 中工作?
  • template &lt; typename... Args &gt; PointScreen(Args&amp;&amp;... args) : Point(std::forward&lt;Args&gt;(args)...) {} 用作可以调用基类的所有 ctor 的构造函数(使用 clang++3.0 进行了尝试)。无论哪种方式,您都需要将 public 放入 PointScreen
  • 该模板 ctor 并没有采用通过 braced-init-list 隐式引入的 initializer_list(因为它的类型没有被推断出来)。如果使用该模板 ctor 解决方法,您需要单独的 ctor 用于初始化列表。

标签: templates inheritance c++11 constructor clang++


【解决方案1】:

正如 cmets 中所指出的,您需要一个支持继承构造函数的编译器。从Apache C++11 overview 可以看出,该功能仅适用于 gcc >= 4.8 和 Clang >= 3.3。

对于较旧的编译器,您必须手动定义所有构造函数,通过 calling the base constructors。有关解决方法的更多详细信息,另请参阅this Q&A

【讨论】:

  • 这就是我尝试过但失败了:你能举一个我如何重新定义构造函数的例子吗?
  • @fuenfundachtzig 基类可以像初始化列表中的常规成员一样初始化:PoinScreen::PointScreen(int x, int y): Point&lt;int&gt;(x, y) {}
  • @fuenfundachtzig Complete live example
  • @DyP tnx,我在平板电脑上,所以输入示例太麻烦了。很高兴看到注入的基类名称也可以在初始化列表中使用(used to be a gcc bug
猜你喜欢
  • 2013-05-21
  • 1970-01-01
  • 1970-01-01
  • 2019-12-14
  • 2014-01-29
  • 2016-12-30
  • 2016-03-04
  • 2017-08-05
  • 1970-01-01
相关资源
最近更新 更多