gpt4 book ai didi

c++ - "Incomplete"对象实例化和输出行为

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:00:32 27 4
gpt4 key购买 nike

下面的代码究竟是如何工作的?

#include <cstdio>

template<class T>
T x = T{};

void foo()
{
class Test
{
public:
Test() { std::printf("Test::Test\n"); }
};

Test t = x<Test>;
}


int main()
{
std::printf("main\n");
}

输出

Test::Test
main

Live example

  • 为什么打印Test::Test首先代替 main
  • 它依赖于哪个标准?它只是 C++1z 吗?我找不到相关的提案。你能给我一个链接吗?
  • 什么是 x在此代码中以及如何Test t = x<Test>作业真的有用吗?

此外,如果我改变std::printf调用 std::cout整个程序崩溃:

#include <iostream>

template<class T>
T x = T{};

void foo()
{
class Test
{
public:
Test() { std::cout << "Test::Test\n"; }
};

Test t = x<Test>;
}


int main()
{
std::cout << "main\n";
}

输出

Segmentation fault      (core dumped) ./a.out

Live example

为什么?

最佳答案

正如其他人已经提到的,您使用了变量模板。

如果我没记错的话,变量模板类似于这样的东西:

template<class T>
struct X {
static T x;
};

template<class T>
T X<T>::x = T{};

然后你使用它,就像这样:

void foo() {
class Test {
public:
Test() { std::printf("Test::Test\n"); }
};

Test t = X<Test>::x;
}

如果您尝试这样做,您将看到相同的结果:coliru .

模板实例化在foo中,并发出初始化静态成员的代码。此初始化发生在 main 之前运行,所以你看到 Test::Test先打印。

至于初始化发生,尽管使用变量的代码从未被调用 - 我假设编译器可能会尝试推理 foo从未在整个程序中被调用,Test作为本地类,其类型不会转义 foo ,从而使实例化X<Test>::x其他任何人都无法访问,并决定将其删除...

...但我想这在链接时需要一些努力,而且我没有看到标准强制要求这种行为。

此外,我不确定是否允许编译器/链接器删除非局部变量的初始化,如果该初始化有副作用的话。

关于c++ - "Incomplete"对象实例化和输出行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37703510/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com