重载解析、定义函数和模板的顺序
Overload resolution, order of defined functions and templates
考虑以下代码片段:
template<class T>
std::enable_if_t<std::is_integral<T>::value, bool> func(T value) {
std::cout << "T\n";
return func(static_cast<int64_t>(value));
}
bool func(int64_t value) {
std::cout << "int64_t\n";
return true;
}
int main() {
func(1);
}
导致无限递归。但是,交换这两个函数的定义顺序(如果 bool func(int64_t value)
在模板一之前定义)有助于避免此问题。
这是为什么?函数重载的顺序重要吗?
Does order of function overloads matter?
从某种意义上说,重载顺序确实很重要,如果在声明潜在重载之前调用重载集,则尚未声明的函数不会参与重载决议。
在函数调用之前声明的重载顺序无关紧要。
当编译器解析第一个函数(模板)时,它对 func
的第二个重载一无所知。解析是从源文件的顶部到底部完成的。
这就是您在使用符号之前需要进行符号声明的原因。这也意味着只要在顶部有一个 声明 of bool func(int64_t);
就可以解决你的问题。
Does order of function overloads matter?
不改变重载解析的结果,而是改变name lookup的结果;这发生在重载决议之前。
(强调我的)
For a name used in global (top-level namespace) scope, outside of any function, class, or user-declared namespace, the global scope before the use of the name is examined:
也就是说在模板化的func
中调用func
,只能找到自身(并加入到重载集中),非模板版本不予考虑完全没有。
如您所见,如果更改它们的声明顺序,将在以下重载决议中找到并考虑两个 func
,并且选择非模板 func
(如预期的那样) .
考虑以下代码片段:
template<class T>
std::enable_if_t<std::is_integral<T>::value, bool> func(T value) {
std::cout << "T\n";
return func(static_cast<int64_t>(value));
}
bool func(int64_t value) {
std::cout << "int64_t\n";
return true;
}
int main() {
func(1);
}
导致无限递归。但是,交换这两个函数的定义顺序(如果 bool func(int64_t value)
在模板一之前定义)有助于避免此问题。
这是为什么?函数重载的顺序重要吗?
Does order of function overloads matter?
从某种意义上说,重载顺序确实很重要,如果在声明潜在重载之前调用重载集,则尚未声明的函数不会参与重载决议。
在函数调用之前声明的重载顺序无关紧要。
当编译器解析第一个函数(模板)时,它对 func
的第二个重载一无所知。解析是从源文件的顶部到底部完成的。
这就是您在使用符号之前需要进行符号声明的原因。这也意味着只要在顶部有一个 声明 of bool func(int64_t);
就可以解决你的问题。
Does order of function overloads matter?
不改变重载解析的结果,而是改变name lookup的结果;这发生在重载决议之前。
(强调我的)
For a name used in global (top-level namespace) scope, outside of any function, class, or user-declared namespace, the global scope before the use of the name is examined:
也就是说在模板化的func
中调用func
,只能找到自身(并加入到重载集中),非模板版本不予考虑完全没有。
如您所见,如果更改它们的声明顺序,将在以下重载决议中找到并考虑两个 func
,并且选择非模板 func
(如预期的那样) .