Очень странный отказ от перегрузки
Я столкнулся с очень странным перегрузкой. Я могу изолировать проблему, но я не могу в жизни понять, что пошло не так.
Код следующий:
#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});
}
Составление результатов в
$ 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.
Две вещи, которые избавляются от проблемы:
- Удаление
Foo(size_t n)
. - Изменение конструктора на
Bar(const Foo<size_t> &A)
.
Очевидно, я хочу сохранить все функции. Итак: Что не так? Как я могу это решить?
Ответы
Ответ 1
Что пошло не так?
Bar A({1,2});
Может интерпретироваться как:
Bar A(Bar{Foo<std::size_t>(1), (bool)2 /*, true*/ });
или же
Bar A(Foo<std::size_t>{1,2} /*, true, true*/);
так неоднозначный вызов.
Как я могу это решить?
Это зависит от результата, которого вы ожидаете, например, добавление explicit
может помочь.
Создание explicit Foo(size_t n)
позволило бы:
Bar A(B{Foo<std::size_t>(1), (bool)2 /*, true*/ });