gpt4 book ai didi

c++ - 模板函数查找

转载 作者:可可西里 更新时间:2023-11-01 18:29:37 25 4
gpt4 key购买 nike

考虑这段代码:

#include <iostream>
#include <vector>

template<typename A>
void foo(A& a) {
std::cout << "the wrong foo" << std::endl;
}

template<typename A>
void do_stuff(A& a) {
foo(a);
}

template<typename X>
void foo(std::vector<X>& a) {
std::cout << "the right foo" << std::endl;
}

int main()
{
std::vector<int> q;
do_stuff(q);
}

为什么调用“错误的”foo?如果删除了 foo 的第一个声明,则调用正确的 foo。

我正在使用 gcc 4.6.3。

更新:如果按以下顺序声明函数,则调用正确的 foo。

template<typename A> void do_stuff(A& a) { ... }
template<typename A> void foo(A& a) { ... }
template<typename X> void foo(std::vector<X>& a) { ... }

最佳答案

观察到的行为是正确的,因为 foo(a) 是一个依赖于类型的表达式:

14.6.2.2 Type-dependent expressions                         [temp.dep.expr]

1) Except as described below, an expression is type-dependent if any
subexpression is type-dependent.

2) this is type-dependent if the class type of the enclosing member
function is dependent (14.6.2.1).

3) An id-expression is type-dependent if it contains

— an identifier associated by name lookup with one or more declarations
declared with a dependent type,
...

在 14.6.4 下(从属名称解析):

14.6.4.2 Candidate functions                              [temp.dep.candidate]

For a function call that depends on a template parameter, the candidate
functions are found using the usual lookup rules (3.4.1, 3.4.2, 3.4.3) except
that:

— For the part of the lookup using unqualified name lookup (3.4.1) or qualified
name lookup (3.4.3), only function declarations from the template definition
context are found.
— For the part of the lookup using associated namespaces (3.4.2), only function
declarations found in either the template definition context or the template
instantiation context are found.

If the function name is an unqualified-id and the call would be ill-formed or
would find a better match had the lookup within the associated namespaces
considered all the function declarations with external linkage introduced in
those namespaces in all translation units, not just considering those
declarations found in the template definition and template instantiation
contexts, then the program has undefined behavior.

“错误的”foo() 被选中是因为它是唯一可见的模板定义点,而“正确的”foo() 不被考虑,因为它不在与函数参数类型关联的命名空间中

如果您修改您的代码,使“正确的”foo() 位于关联的命名空间中,它将被选中而不是“错误的”foo()。 (在这种特殊情况下,标准不允许这样做,所以不要执行以下操作,但是对于您自己的命名空间/类型,这应该是这样工作的)

#include <iostream>
#include <vector>

template<typename A> void foo(A& a)
{
std::cout << "the wrong foo" << std::endl;
}

template<typename A>
void do_stuff(A& a) {
foo(a);
}

namespace std { // evil, don't do this with namespace std!

template<typename X>
void foo(std::vector<X>& a) {
std::cout << "the right foo" << std::endl;
}

}

int main()
{
std::vector<int> q;
do_stuff(q); // calls the "right" foo()
}

关于c++ - 模板函数查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12530174/

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