I am writing a small library for working with polynomials.
The main class is called poly and it contains 4 overloaded constructors.
An object of class poly is a representation of one polynomial.
Full code can be viewed here: https://github.com/IQ8QI/polynomial-lib
In ./test-poly/test-all.cpp I am trying to create an object of class poly:
poly::poly my_poly = poly::poly((double)6.0, -2.0, 4.0);
Constructors of class poly are:
//Create polynomial using just numbers
poly(double values...);
//Create polynomial using vector<double>
poly(vector<double> values);
//Create polynomial with non-zero base
poly(int base, double values...);
//Create polynomial with non-zero base and vector
poly(int base, vector<double> values);
Unfortunately, I am receiving a compilation error:
./test-all.cpp:20:63: error: call of overloaded ‘poly(double, double, double)’ is ambiguous
20 | poly::poly my_poly = poly::poly((double)6.0, -2.0, 4.0);
| ^
In file included from ./test-all.cpp:3:
././../polynomial-lib/polynomial.hpp:22:17: note: candidate: ‘poly::poly::poly(int, double, ...)’
22 | poly(int base, double values...);
| ^~~~
././../polynomial-lib/polynomial.hpp:16:17: note: candidate: ‘poly::poly::poly(double, ...)’
16 | poly(double values...);
| ^~~~
I understand that the compiler is unable to determine which constructor to use.
I want to stay with solution that there are 4 constructors poly().
To resolve the issue, I can change 2 of the constructors into builder functions, but I don't like it:
//Create polynomial with non-zero base
poly special_poly(int base, double values...){
poly temp_poly = poly(values...);
temp_poly.set_base(base);
return temp_poly;
}
//Create polynomial with non-zero base and vector
poly special_poly(int base, vector<double> values){
poly temp_poly = poly(values);
temp_poly.set_base(base);
return temp_poly;
}
Can it be done without builder functions?
You do not need c varargs when you can use c++ variadic templates which are typesafe. However, you already have a constructor that takes a
std::vector, so I see no need for more than a single constructor:I stayed with
std::vectorpassed by value because thats what you asked for. Though, if you never actually need to pass an already constructed vector, but just a list ofdoubles to the constructor you can change the argument to be astd::initializer_list<double>. If you stay withstd::vectorconsider to pass it as rvalue reference (see below comment by Jan Schultke).