I have encountered a very strange overload failure. I am able to isolate the problem, but I cannot for the life of it figure out what goes wrong.
The code is the following
#include <vector>
#include <iostream>
template<class X>
class Foo
{
public:
Foo(const std::initializer_list<X> &A){}
Foo(size_t n){}
};
class Bar
{
public:
Bar() = default;
Bar(const Foo<size_t> &A, bool a=true, bool b=true){};
};
int main()
{
Bar A({1,2});
}
Compiling results in
$ clang++ -std=c++14 so.cpp
so.cpp:21:11: error: call to constructor of 'Bar' is ambiguous
Bar A({1,2});
^ ~~~~~
so.cpp:12:11: note: candidate is the implicit move constructor
class Bar
^
so.cpp:12:11: note: candidate is the implicit copy constructor
so.cpp:16:7: note: candidate constructor
Bar(const Foo<size_t> &A, bool a=true, bool b=true){};
^
1 error generated.
The two things that get rid of the problem are:
Foo(size_t n)
.Bar(const Foo<size_t> &A)
.Obviously I want to keep all features. So: What goes wrong? How can I solve it?
Overload failures refer to the ductile or brittle fracture of a material when stresses exceed the load-bearing capacity of a material.
Overload fractures generally fall into two (2) categories, Brittle and Ductile.
Ductile Overload Fracture occurs as force is applied to a part causing permanent distortion and subsequent fracture. As excessive force is applied to the part, it bends or stretches. As more force is applied, it finally breaks. Ductile fractures are easy to recognize because the parts are distorted.
The existence of ratchet marks indicates the presence of multiple crack initiation sites and high stress concentration conditions. Ratchet marks are created when cracks initiated at different positions are joined together, creating steps on the fracture surface (Figure 4a).
What goes wrong?
Bar A({1,2});
Can be interpreted as:
Bar A(Bar{Foo<std::size_t>(1), (bool)2 /*, true*/ });
or
Bar A(Foo<std::size_t>{1,2} /*, true, true*/);
so ambiguous call.
How can I solve it?
It depends of which result you expect, adding explicit
might help for example.
Making explicit Foo(size_t n)
would allow only:
Bar A(B{Foo<std::size_t>(1), (bool)2 /*, true*/ });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With