代码不会在 g++ 中编译,而在 clang++ 中会编译
code does not compile in g++ while it does in clang++
所以我有这个非常短的代码:
test.cpp
class Base {
public:
Base(int i) {};
};
class Child : public virtual Base {
using Base::Base;
};
int main(int argc, char * argv[]) {
auto *child = new Child(1);
return 0;
};
它在 clang++ (3.8.0) 下编译良好:
$ clang++ test.cpp -std=c++11
在 g++ (5.4.0) 下失败时:
$ g++ test.cpp -std=c++11
test.cpp: In function ‘int main(int, char**)’:
test.cpp:14:30: error: use of deleted function ‘Child::Child(int)’
auto *child = new Child(1);
^
test.cpp:8:17: note: ‘Child::Child(int)’ is implicitly deleted because the default definition would be ill-formed:
using Base::Base;
^
test.cpp:8:17: error: no matching function for call to ‘Base::Base()’
test.cpp:3:9: note: candidate: Base::Base(int)
Base(int i) {};
^
test.cpp:3:9: note: candidate expects 1 argument, 0 provided
test.cpp:1:7: note: candidate: constexpr Base::Base(const Base&)
class Base {
^
test.cpp:1:7: note: candidate expects 1 argument, 0 provided
test.cpp:1:7: note: candidate: constexpr Base::Base(Base&&)
test.cpp:1:7: note: candidate expects 1 argument, 0 provided
出于某种原因,g++ 期望 Base
class 具有默认构造函数。这是为什么?
编辑: 这也无法复制。此代码:
auto child = Child(1);
在 g++ 下产生同样的错误,而这个:
Child child(1);
工作正常。但是我还是不明白为什么?
编辑 2: 没有 virtual
关键字,它在两个编译器下都能正常工作。
我认为这是一个 g++ 错误。
来自N2540,本人强调:
Typically, inheriting constructor definitions for classes with virtual bases will be ill-formed, unless the virtual base supports default initialization, or the virtual base is a direct base, and named as the base forwarded-to. Likewise, all data members and other direct bases must support default initialization, or any attempt to use a inheriting constructor will be ill-formed. Note: ill-formed when used, not declared.
据我所知,您的示例完全符合我强调的条件,因此我认为它应该可行。但是请注意,这是一份工作草案变更提案;在纳入最终标准之前,它可能已经改变。但我希望如果有任何改变,它可能会允许更多的案例,而不是禁止更多的案例。
也许了解实际标准的人可以仔细检查一下。
所以我有这个非常短的代码:
test.cpp
class Base {
public:
Base(int i) {};
};
class Child : public virtual Base {
using Base::Base;
};
int main(int argc, char * argv[]) {
auto *child = new Child(1);
return 0;
};
它在 clang++ (3.8.0) 下编译良好:
$ clang++ test.cpp -std=c++11
在 g++ (5.4.0) 下失败时:
$ g++ test.cpp -std=c++11
test.cpp: In function ‘int main(int, char**)’:
test.cpp:14:30: error: use of deleted function ‘Child::Child(int)’
auto *child = new Child(1);
^
test.cpp:8:17: note: ‘Child::Child(int)’ is implicitly deleted because the default definition would be ill-formed:
using Base::Base;
^
test.cpp:8:17: error: no matching function for call to ‘Base::Base()’
test.cpp:3:9: note: candidate: Base::Base(int)
Base(int i) {};
^
test.cpp:3:9: note: candidate expects 1 argument, 0 provided
test.cpp:1:7: note: candidate: constexpr Base::Base(const Base&)
class Base {
^
test.cpp:1:7: note: candidate expects 1 argument, 0 provided
test.cpp:1:7: note: candidate: constexpr Base::Base(Base&&)
test.cpp:1:7: note: candidate expects 1 argument, 0 provided
出于某种原因,g++ 期望 Base
class 具有默认构造函数。这是为什么?
编辑: 这也无法复制。此代码:
auto child = Child(1);
在 g++ 下产生同样的错误,而这个:
Child child(1);
工作正常。但是我还是不明白为什么?
编辑 2: 没有 virtual
关键字,它在两个编译器下都能正常工作。
我认为这是一个 g++ 错误。
来自N2540,本人强调:
Typically, inheriting constructor definitions for classes with virtual bases will be ill-formed, unless the virtual base supports default initialization, or the virtual base is a direct base, and named as the base forwarded-to. Likewise, all data members and other direct bases must support default initialization, or any attempt to use a inheriting constructor will be ill-formed. Note: ill-formed when used, not declared.
据我所知,您的示例完全符合我强调的条件,因此我认为它应该可行。但是请注意,这是一份工作草案变更提案;在纳入最终标准之前,它可能已经改变。但我希望如果有任何改变,它可能会允许更多的案例,而不是禁止更多的案例。
也许了解实际标准的人可以仔细检查一下。