Reputation:
I want to create a templated math vector class. But it says code editor says ambiguous constructor.
I use only header file!!
.h
template<class T>
class MathVec {
private:
std::vector<T> mathVec;
size_t dimension;
public:
MathVec(size_t dim);
MathVec(size_t dim, ...);
MathVec(const MathVec& other);
MathVec();
void print();
};
template<class T>
MathVec<T>::MathVec(size_t dim) {
this->dimension = dim;
this->mathVec = std::vector<T>(dim,0);
}
template<class T>
MathVec<T>::MathVec(size_t dim, ...) {
this->mathVec = std::vector<T>(dim);
this->dimension = dim;
va_list list;
va_start(list, dim);
for (size_t i = 0; i < dim; i++){
this->mathVec[i] = va_arg(list, T);
}
va_end(list);
}
template<class T>
MathVec<T>::MathVec(const MathVec & other) {
this->dimension = other.dimension;
this->mathVec = other.mathVec;
}
template<class T>
MathVec<T>::MathVec() {
this->dimension = 0;
}
template<class T>
void MathVec<T>::print() {
for(int i = 0; i < this->dimension; ++i)
std::cout << this->mathVec[i] << " ";
std::cout << std::endl;
}
In the main.cpp file I use the following code it is working.
MathVec<int> vect(3,1,2,3);
vect.print();
But if I use the following code it is not working
MathVec<int> vect(1);
vect.print();
The error message is the following.
main.cpp:9:18: error: call to constructor of 'MathVec<int>' is ambiguous
mathvec.h:14:9: note: candidate constructor
mathvec.h:15:9: note: candidate constructor
mathvec.h:16:9: note: candidate constructor
I assume that wrong with the ellipsis, but I do not know what can be the problem, and how to solve this issue.
Upvotes: 1
Views: 129
Reputation: 25
In general I would avoid using C style variadic arguments, check variadic templates instead (C++11) or fold expressions (C++17)
Upvotes: 0
Reputation: 21936
Modern C++ has better way to accomplish that. Create the following constructor:
MathVec( std::initializer_list<T> values )
Usage:
MathVec<int> vect( { 1, 2, 3 } );
Upvotes: 1
Reputation: 96
may I offer some improvements to your design? There is no reason to pass dimension as a parameter to constructor. I think be better to make it template parameter. Thus, when you try mix in some expression matrices with different dimensions, you catch error at compile time, not when program executes ;)
Working example:
#include <vector>
#include <iostream>
template <typename T, unsigned int dim>
class Matrix
{
const unsigned int m_dim = dim;
std::vector<T> m_vec;
public:
Matrix(): m_vec(std::vector<T>(m_dim, 0)) {}
virtual ~Matrix() {}
//suppose, we want m_vec be R/O for public
const std::vector<T>& Read() {return m_vec;}
};
int main(int, char **)
{
Matrix<double, 4> m;
for (auto& x : m.Read())
std::cout << x << std::endl;
}
Upvotes: 1
Reputation: 805
My guess would be that the compiler does not know what constructor to call, as these two:
MathVec(size_t dim);
MathVec(size_t dim, ...);
can both be called by
MathVec<int> vect(1);
Upvotes: 1