此代码段不会使用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
会产生预期的效果。
答案 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)
如果您的问题是隐式double
到Polyline
,您可以将构造函数标记为显式:
explicit PolyLine (int initLength = INIT_LENGTH);