Consider the following little program:
#include <vector>
class A {
int a;
int b;
public:
explicit A() = default;
A(int _a, int _b) : a(_a), b(_b) {}
int f(const A& a) { return 0; }
int f(std::vector<int> a) { return 1; }
};
int g(const A& a) { return 2; }
int g(std::vector<int> a) { return 3; }
int main() {
A a(1,2);
// a.f({}); //ambiguous according to gcc
g({}); //ambiguous according to gcc
return 0;
}
GCC 10.2 refuse to compile it: it says the call to g({})
and a.f({})
are ambiguous. Clang compile this without complaining.
It seems to me that g(const A&)
shouldn't be considered in overload resolution because implicit conversion from no arguments is not allowed: A::A()
is marked explicit.
I am not confident that the fault isn't mine and, in any case, I'd like to find a workaround.
Is there another default generated constructor that could be the source of my problem?
You can try it on the compiler explorer.
This SO post was brought to my attention. Its answer tells us which compiler is right: it's GCC. But it does not tell us how to obtain the desired behavior with those overload rules.
{}
might be allowed to use an explicit constructor, I'm not sure. It's definitely not an implicit conversion... – Gereronint
argument (instead of default constructor), only clang accepts it Demo... – Arapahostd::vector
variant gcc complains that explicit ctor ofA
cannot be used. – Doublegangerclass A
members, another ctor, methods etc ideone.com/tgyAfg – Doubleganger