c++ - Can you explain this overload resolution behavior? -
this code snippet not compile using vs2013 or 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); }
because no instance of c1
constructor matches argument list (double, int)
, when replace c2
polyline
compile , 1.5
somehow cast polyline
. test inside large project many dependencies, can fit fragment of header here:
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 x axis coordinates of polyline nodes. vector<float> y; ///< vector 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()) {};
what circumstances when polyline
can cast double
?
edit
after reading first answers, reduced example to:
class polyline { public: polyline(int = 7) {}; };
marking polyline
constructor explicit
produces desired effect.
you trying call c1::c1(double, int)
. there 2 names found:
template <typename t> c1::c1(t, t); c1::c1(const c2&, int);
the first 1 not viable - arguments have different types can't call template on single type.
so leaves second one. second 1 viable if can construct c2
double
. in initial example, c2
incomplete, can't construct anything, hence can't compile. however, polyline
have constructor:
polyline (int );
as part of conversion sequence, allowed 0 or 1 standard conversion , 0 or 1 user-defined conversion. double --> int
allowed standard conversion , int --> polyline
allowed user-defined conversion.
as such, c1::c1(const polyline&, int)
viable constructor. since it's viable constructor, makes trivially best viable constructor.
Comments
Post a Comment