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

Popular posts from this blog

facebook - android ACTION_SEND to share with specific application only -

python - Creating a new virtualenv gives a permissions error -

javascript - cocos2d-js draw circle not instantly -