Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Very strange overload failure

Tags:

c++

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:

  • Removing Foo(size_t n).
  • Changing the constructor to Bar(const Foo<size_t> &A).

Obviously I want to keep all features. So: What goes wrong? How can I solve it?

like image 891
Tom de Geus Avatar asked Jun 03 '18 16:06

Tom de Geus


People also ask

What is an overload failure?

Overload failures refer to the ductile or brittle fracture of a material when stresses exceed the load-bearing capacity of a material.

What types of failures occur when a component is momentarily overloaded?

Overload fractures generally fall into two (2) categories, Brittle and Ductile.

What causes ductile overload?

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.

What do ratchet marks indicate?

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).


1 Answers

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*/ });
like image 113
Jarod42 Avatar answered Oct 14 '22 11:10

Jarod42