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:
#include <vector>
struct poly{
std::vector<double> coeffs;
int base = 0;
poly(std::vector<double> c,int b = 0) : coeffs(std::move(c)),base(b) {}
};
int main() {
poly p1{{1.0,2.0,3.0}};
poly p2{{1.0,2.0,3.0},0};
}
I stayed with std::vector
passed by value because thats what you asked for. Though, if you never actually need to pass an already constructed vector, but just a list of double
s to the constructor you can change the argument to be a std::initializer_list<double>
. If you stay with std::vector
consider to pass it as rvalue reference (see below comment by Jan Schultke).