A class is implemented as follows, there are three construction methods, and then an empty sequence is declared through a macro to initialize the class,
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#define EMPTY_LIST {}
class sample{
private:
typedef uint64_t s_type;
vector<s_type> _vec;
public:
sample() {}
sample(const sample& other) : _vec(other._vec) {{
cout << "const lvalue" << endl;
}}
sample(sample&& other) : _vec(std::move(other._vec)) {{
cout << "rvalue ref" << endl;
}}
sample(const vector<size_t>& array) {
cout << "array" << endl;
};
};
int main(){
sample ft(EMPTY_LIST);
return 0;
}
But the compilation reports an error. What is the reason?
# g++ sample.cc -o sample
sample.cc: In function ‘int main()’:
sample.cc:30:25: error: call of overloaded ‘sample(<brace-enclosed initializer list>)’ is ambiguous
sample ft(EMPTY_LIST);
^
sample.cc:22:3: note: candidate: ‘sample::sample(const std::vector<long unsigned int>&)’
sample(const vector<size_t>& array) {
^~~~~~
sample.cc:19:3: note: candidate: ‘sample::sample(sample&&)’
sample(sample&& other) : _vec(std::move(other._vec)) {{
^~~~~~
sample.cc:16:3: note: candidate: ‘sample::sample(const sample&)’
sample(const sample& other) : _vec(other._vec) {{
^~~~~~
maybe the empty array defined by the macro is an empty instance? So is it ambiguous? Or is it because of the C++ standard?
sample(const vector<size_t>& array){}can be equally converted to any of the 3 types you've provided as constructor parameters. You either need to give it a reason to prefer one over the others, or change it from{}to something else that is more explicit.