【发布时间】:2020-05-25 15:55:56
【问题描述】:
让我们考虑这个类:
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 中的一个问题。事实上,只有 7.x 版本的 gcc 编译了这个示例。 gcc 6.4 没有。 gcc 8.1 也没有。也不叮当。 msvc 都没有。
你能确认这里没有UB,这真的是一个编译器错误吗?
【问题讨论】:
-
auto p = new A{};有错字吗?不应该是auto p = new T{};吗? -
@NutCracker my bad
using T = std::array<A, 2>;不应该出现在最后一个程序中。我真的想分配一个A以表明问题仅在使用std::array时出现。我已经更新了我的问题。 -
@NutCracker 不,
A在这种情况下不是聚合。
标签: c++ arrays constructor compiler-errors new-operator