让我们考虑这堂课:
class A {
public:
A() = delete;
A(int i) :
i_m(i) {
std::cout << __PRETTY_FUNCTION__ << ' ' << i_m << '\n';
}
~A() {
std::cout << __PRETTY_FUNCTION__ << ' ' << i_m << '\n';
}
private:
int i_m{1234567890};
};
默认构造函数被明确删除,因此AFAIK A
只能由整数构造。永远不会使用数据成员i_m
的默认初始化。
让我们考虑这个程序:
int main() {
using T = std::array<A, 2>;
//T a;
// error: use of deleted function 'std::array<A, 2>::array()'
// note: 'std::array<A, 2>::array()' is implicitly deleted because the default definition would be ill-formed
// error: use of deleted function 'A::A()'
//T b{};
// error: use of deleted function 'A::A()'
}
再次,对我来说,这似乎完全没问题。
现在让我们考虑其他程序:
int main() {
using T = std::array<A, 2>;
auto foo = new T{};
delete foo;
auto foo_init = new T{1, 2};
delete foo_init;
// auto zorg = new T();
// delete zorg;
// error: use of deleted function 'std::array<A, 2>::array()'
// note: 'std::array<A, 2>::array()' is implicitly deleted because the default definition would be ill-formed:
// error: use of deleted function 'A::A()'
auto zorg_init = new T({3, 4});
delete zorg_init;
}
此代码确实编译(无警告)并生成以下输出:
A::~A() 0
A::~A() 38870160
A::A(int) 1
A::A(int) 2
A::~A() 2
A::~A() 1
A::A(int) 3
A::A(int) 4
A::~A() 4
A::~A() 3
现在对我来说似乎有些[[不是很好”。怎么可能auto foo = new T{};
行不被认为格式错误?这里完全绕过了类A
的初始化。
int main() {
auto p = new A{};
delete p;
}
错误是预期的:
error: use of deleted function 'A::A()'
我使用以下选项测试了这些代码:-Wall -Wextra -pedantic -std=c++17
。gcc -v
给出:gcc version 7.2.0 (x86_64-posix-sjlj-rev0, Built by MinGW-W64 project)
在我的计算机上。任何解释将不胜感激:)
PS:在Compiler Explorer中进行详尽测试(与示例https://godbolt.org/z/5VZLU_结合使用)之后,看来这是gcc 7.x中的问题。实际上,只有gcc的7.x版本可以编译此示例。 gcc 6.4并非没有。 gcc 8.1都不是。既不。 msvc都没有。您可以确认此处没有UB,这确实是编译器错误吗?
如果您看以下使用空括号对而不是初始化列表的代码:
int main() {
using T = std::array<A, 2>;
auto foo = new T(); // here
delete foo;
return 0;
}
它将抛出错误:错误:使用删除的功能'std :: array :: array()'
auto foo = new T();
与使用初始化程序列表并使用不同于7.x的编译器版本进行编译时出现的错误相同。