gpt4 book ai didi

c++ - 为什么我可以在没有前向声明的情况下调用函数模板?

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

如果一个普通函数调用一个尚未声明的函数,我会得到一个编译时错误:

void foo(int x)
{
bar(x); // ERROR: bar has not been declared yet
}

void bar(int x)
{
std::cout << x << '\n';
}

int main()
{
foo(42);
}

解决方法是前向声明被调用的函数,或者切换定义的顺序。

但是,对于函数模板,这些修复似乎不是必需的:

template<typename T>
void foo(T x)
{
bar(x); // OKAY
}

template<typename T>
void bar(T x)
{
std::cout << x << '\n';
}

int main()
{
foo(42);
}

这编译得很好。这是为什么?当编译器看到 bar(x) 时,它为什么不报错?

(我使用的是 g++ 4.6.3)

最佳答案

这是一个“为什么天空是用砖砌成的”类型的问题。即,一个问为什么假的是真的问题。在 C++ 中,您的代码并不是合法的。

Live example ,正如您在 gcc 4.8 中看到的那样,这实际上并没有编译。

我想问题“为什么 gcc 4.6 让这段代码编译”仍然存在。编译器在编写 template 时早期所做的事情之一expanders 将它们视为类似于宏的东西。当它们被声明时几乎不会做任何事情,当它们被实例化时一切都会被查找。

编译器现在倾向于在 template 时做更多的事情。被声明,并且在实例化时更少。这是 C++ 标准要求的,或者至少更接近。

碰巧,ADL 可以解决这个问题:bar找到 bar 的查找通过 ADL 不必在 foo 处可见已写入,而是在实例化时写入。

gcc 4.8 的错误信息很容易解释:

prog.cpp: In instantiation of ‘void foo(T) [with T = int]’:
prog.cpp:16:7: required from here
prog.cpp:6:10: error: ‘bar’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
bar(x); // OKAY
^
prog.cpp:10:6: note: ‘template<class T> void bar(T)’ declared here, later in the translation unit
void bar(T x)
^

这些要求可能已在 C++11 中更改或阐明,因此 gcc 4.6 的行为可能在 C++03 标准下是合法的。

关于c++ - 为什么我可以在没有前向声明的情况下调用函数模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18674387/

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