У меня есть два класса, A и B, и B является производным от A. A имеет несколько конструкторов (2 в приведенном ниже примере). B имеет один дополнительный элемент для инициализации (который имеет инициализатор по умолчанию).
Как добиться того, чтобы B можно было сконструировать с помощью одного из конструкторов A без необходимости вручную переписывать все перегруженные версии конструктора из A в B?
(В приведенном ниже примере мне пришлось бы предоставить четыре конструктора для B:B():A(){}
, B(string s):A(s){}
, B(int b):A(),p(b){}
, B(string s, int b):A(s),p(b){}
вместо двух, по крайней мере, если игнорировать возможность аргументов по умолчанию).
Мой подход был идеальной переадресацией, однако следующий сценарий приводит к ошибке:
#include <utility>
#include <string>
struct A {
A(const std::string& a) : name(a) {}
A(){}
virtual ~A(){}
std::string name;
};
struct B : public A {
template<typename... Args>
B(Args&&... args) : A(std::forward<Args>(args)...) {}
B(const std::string& a, int b) : A(a), p(b) {}
int p = 0;
};
int main()
{
B b1("foo");
B b2("foobar", 1);
}
Для b2 GCC жалуется на no matching function for call to 'A::A(const char [5], int)
. Очевидно, он пытается вызвать идеальный конструктор пересылки, который явно не должен работать, вместо второго конструктора B.
Почему компилятор не видит второй конструктор и вместо этого вызывает его? Существуют ли технические причины, по которым компилятор не может найти правильный конструктор B? Как я могу исправить это поведение?
Точное сообщение об ошибке:
main.cpp: In instantiation of 'B::B(Args&& ...) [with Args = {const char (&)[5], int}]':
main.cpp:26:19: required from here
main.cpp:15:54: error: no matching function for call to 'A::A(const char [5], int)'
B(Args&&... args) : A(std::forward<Args>(args)...) {}
^
main.cpp:6:5: note: candidate: A::A()
A(){}
^
main.cpp:6:5: note: candidate expects 0 arguments, 2 provided
main.cpp:5:5: note: candidate: A::A(const string&)
A(const std::string& a) : name(a) {}
^
main.cpp:5:5: note: candidate expects 1 argument, 2 provided
main.cpp:4:8: note: candidate: A::A(const A&)
struct A {
^
main.cpp:4:8: note: candidate expects 1 argument, 2 provided