I have a class––roughly similar to the one below––that takes a map as the only argument to its only constructor.
#include <iostream>
#include <map>
using namespace std;
class Dict {
public:
Dict (map<int, int> contents) {
elements = contents;
}
int getElement (int i) {
return elements[i];
}
map<int, int> elements;
};
int main() {
Dict* test0 = new Dict({{1, 2}, {3, 4}}); /* Succeeds */
Dict* test1 = new Dict({{1, 2}}); /* Fails */
}
As mentioned in the comments above, the first constructor doesn't throw an error; it's consistent with answers such as this. The ambiguous call error is as follows:
main.cpp:43:36: error: call of overloaded 'Dict()' is ambiguous
Dict* test1 = new Dict({{1, 2}}); /* Fails */
^
main.cpp:16:5: note: candidate: Dict::Dict(std::map)
Dict (map<int, int> contents) {
^
main.cpp:14:7: note: candidate: Dict::Dict(const Dict&)
class Dict {
^
main.cpp:14:7: note: candidate: Dict::Dict(Dict&&)
If the keys and values in the map are of different types (for instance, if Dict()
takes a map of ints to booleans and I call new Dict({{1, true}})
), this error doesn't arise and the code works as expected.
How is this single constructor ambiguous? Why is it ambiguous specifically in the case where there is one mapping between two objects of the same type? Are there any obvious work-arounds in vanilla C++?