C++ &引用;“不完整”;对象实例化和输出行为
下面的代码究竟是如何工作的C++ &引用;“不完整”;对象实例化和输出行为,c++,c++17,C++,C++17,下面的代码究竟是如何工作的 #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"); }
#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
- 它所依据的标准是什么?它只是C++1z吗?我找不到相关的建议。你能给我一个链接吗
- 此代码中的
是什么?测试t=x作业实际上是如何工作的x
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";
}
为什么?正如其他人已经提到的,您使用了变量模板 如果我没有弄错的话,变量模板类似于以下内容:
template<class T>
struct X {
static T x;
};
template<class T>
T X<T>::x = T{};
模板
结构X{
静态tx;
};
模板
tx::X=T{};
然后使用它,它将类似于:
void foo() {
class Test {
public:
Test() { std::printf("Test::Test\n"); }
};
Test t = X<Test>::x;
}
void foo(){
课堂测试{
公众:
Test(){std::printf(“Test::Test\n”);}
};
试验t=X::X;
}
如果尝试此操作,您将看到相同的结果:
模板在foo
中实例化,并发出初始化静态成员的代码。
此初始化发生在运行main
之前,因此您会看到首先打印的Test::Test
至于初始化,尽管使用变量的代码从未被调用-我想编译器可以尝试推断整个程序中从未调用foo
,Test
是一个本地类,其类型不会转义foo
,因此,使实例化X::X
对其他任何人都不可访问,并决定将其删除
…但我想这需要在链接时付出一些努力,而我看不到标准规定的这种行为
此外,我不确定编译器/链接器是否允许删除非局部变量的初始化,如果该初始化有副作用。Google“variable template”。@sleep tight pupper好的,谢谢。为什么它实例化了对
foo
函数的w/o调用?:“除非变量模板专门化已显式实例化或显式专门化,否则在使用专门化时,变量模板专门化将隐式实例化”
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;
}