Inheriting constructor and providing new overload: No arguments base constructor seems to not participate in overload resolution 继承构造函数并提供新的重载:无参数基构造函数似乎不参与重载决议
Inheriting constructor and providing new overload: no arguments base constructor seems to not participate in overload resolution
测试显示异常行为(c++14
、g++ 4.9.1
、clang 3.5.5
):
总结一下:
- 如果
B
没有提供它可以使用的其他构造函数A::A()
- 如果
B
提供它不能使用的其他构造函数 A::A()
,但它使用 A::A(whatever arguments)
,这是意外行为(至少对我而言)。
设置 1:
struct A {
A() {};
A(int) {}; // with or without this overload the result are the same
};
struct B : A {
using A::A;
};
B b0{}; // OK
设置 2:
struct A {
A() {}; // with a default constructor instead (empty class A)
// the results are the same
};
struct B : A {
using A::A;
B(int){}
};
B b0{}; // no matching constructor
B b1{24}; // OK
设置 3:
struct A {
A() {};
A(int) {};
};
struct B : A {
using A::A;
B(int, int){}
};
B b0{}; // no matching constructor
B b1{24}; // OK
B b2{24, 42}; // OK
为什么会这样,怎么会这样"fixed"。
我不能告诉你这样做的理由,但我至少可以告诉你这是标准规定的:
[C++11: 12.9/3]
: For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the class where the using-declaration appears. [..]
由于默认 B()
调用默认 A()
,您可以 "fix" 像这样:
struct B : A
{
B() = default;
using A::A;
B(int, int){}
};
(live demo)
以下 wording from the original proposal (n2540) 表明此修复程序的简便性和对称性或多或少是决定背后的驱动因素,但我仍然觉得有些不尽如人意。好吧。
Copy and default constructors are not forwarded, deferring to the existing rules for implicitly declaring copy/default constructors.
测试显示异常行为(c++14
、g++ 4.9.1
、clang 3.5.5
):
总结一下:
- 如果
B
没有提供它可以使用的其他构造函数A::A()
- 如果
B
提供它不能使用的其他构造函数A::A()
,但它使用A::A(whatever arguments)
,这是意外行为(至少对我而言)。
设置 1:
struct A {
A() {};
A(int) {}; // with or without this overload the result are the same
};
struct B : A {
using A::A;
};
B b0{}; // OK
设置 2:
struct A {
A() {}; // with a default constructor instead (empty class A)
// the results are the same
};
struct B : A {
using A::A;
B(int){}
};
B b0{}; // no matching constructor
B b1{24}; // OK
设置 3:
struct A {
A() {};
A(int) {};
};
struct B : A {
using A::A;
B(int, int){}
};
B b0{}; // no matching constructor
B b1{24}; // OK
B b2{24, 42}; // OK
为什么会这样,怎么会这样"fixed"。
我不能告诉你这样做的理由,但我至少可以告诉你这是标准规定的:
[C++11: 12.9/3]
: For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the class where the using-declaration appears. [..]
由于默认 B()
调用默认 A()
,您可以 "fix" 像这样:
struct B : A
{
B() = default;
using A::A;
B(int, int){}
};
(live demo)
以下 wording from the original proposal (n2540) 表明此修复程序的简便性和对称性或多或少是决定背后的驱动因素,但我仍然觉得有些不尽如人意。好吧。
Copy and default constructors are not forwarded, deferring to the existing rules for implicitly declaring copy/default constructors.