你能解释一下这种重载决议行为吗?

时间:2015-06-13 18:18:41

标签: c++

此代码段不会使用VS2013或ICC 16进行编译:

class C2;

class C1
{
public:
  float x, y;

  template<typename T>
  C1 (T x, T y) : x(static_cast<float>(x)), y(static_cast<float>(y)) {};
  C1 (const C2 &a, int i) : x(0), y(0) {};
};

void main()
{
    C1 p(1.5, 2);
}

因为C1构造函数的实例没有与参数列表(double, int)匹配,但是当我用C2替换PolyLine时,它会编译并且1.5以某种方式被转换到PolyLine。我在一个有很多依赖项的大型项目中测试它,所以我只能在这里放入标题的一个片段:

class PolyLine 
{
protected:
    enum {INIT_LENGTH = 16};

public:
  typedef float (PolyLine::*Fit)(Point2D&, Point2D&, const int, const int, const float) const;

    vector<float> x;  ///< Vector with X axis coordinates of polyline nodes.
    vector<float> y;  ///< Vector with Y axis coordinates of polyline nodes.

    PolyLine (int initLength = INIT_LENGTH);
    PolyLine (const PolyLine &poly, int firstNode = -1, int lastNode = -1);
    PolyLine (const PolyLine &poly, const float MAX_ERROR, vector<int> *nodeMap = 0);
    PolyLine (ifstream* input);
  PolyLine (string fileName)  {loadTxt (fileName);};
    PolyLine (const float SAMPLING_RESOLUTION, PolyLine &poly);
    PolyLine (const vector<float> &v, float step = 1.0);
    PolyLine (const vector<int> &v, float step = 1.0);
    PolyLine (const deque<float> &x, const deque<float> &y) : x(x.begin(), x.end()), y(y.begin(), y.end()) {};

PolyLine投放到double时的情况是什么?

修改

在阅读完第一个答案后,我将此示例缩减为:

class PolyLine 
{
public:
  PolyLine(int i = 7) {};
};

标记PolyLine构造函数explicit会产生预期的效果。

2 个答案:

答案 0 :(得分:7)

您正试图致电C1::C1(double, int)。找到了两个名称:

template <typename T> C1::C1(T, T);
C1::C1(const C2&, int);

第一个不可行 - 您的参数有不同的类型,因此您无法在单个类型上调用模板。

这样就留下了第二个。如果你可以从C2构建double,那么第二个是可行的。在您的初始示例中,C2不完整,因此您无法从任何构造它,因此无法编译。但是,对于PolyLine,我们确实有这个构造函数:

PolyLine (int );

作为转换序列的一部分,我们可以进行零次或一次标准转换以及零次或一次用户定义转换。 double --> int是允许的标准转化,int --> PolyLine是允许的用户定义转化。

因此,C1::C1(const PolyLine&, int)是一个可行的构造函数。因为它是唯一可行的构造函数,所以它使它成为最好的可行构造函数。

答案 1 :(得分:1)

如果您的问题是隐式doublePolyline,您可以将构造函数标记为显式:

explicit PolyLine (int initLength = INIT_LENGTH);