定义模板后声明函数

2024-02-22

假设我有一个模板函数:

template <class T>
void tfoo( T t )
{
    foo( t );
}

后来我想将它与类型一起使用,所以我声明/定义一个函数并尝试调用它:

void foo( int );

int main()
{
    tfoo(1);
}

我从 g++ 收到错误:

“foo”未在此范围内声明,并且在实例化时通过参数相关查找未找到任何声明 [-fpermissive] 脚 );

为什么它找不到void foo(int)在实例化点?那时就宣布了。有没有办法让它工作(不移动声明foo在模板之前)?


foo你的情况是附属名称,因为如果参数和参数类型取决于模板参数,则函数选择取决于类型。这意味着foo是按照以下规则查找的依赖查找.

和...之间的不同依赖的 and 非依赖性查找是在依赖查找的情况下ADL 提名的​​命名空间被视为extended:它们使用从模板实例化点可见的额外名称进行扩展(tfoo根据您的情况致电)。其中包括出现在模板声明之后的名称。这里的关键点是onlyADL 命名的命名空间就是以这种方式扩展的。

(By ADL 命名的命名空间我指的是命名空间有关联函数参数类型,因此被依赖名称查找规则考虑在内。请参阅“3.4.2 依赖于参数的名称查找”)

在你的情况下,参数有类型int. int是一个基本类型。基本类型没有关联的命名空间(请参阅“3.4.2 参数相关名称查找”),这意味着它不通过 ADL 指定任何命名空间。在您的示例中,ADL 根本不涉及。从属名称查找foo在这种情况下与非依赖查找没有什么不同。它将无法看到您的foo,因为它已声明below模板。

注意与以下示例的区别

template <class T> void tfoo( T t )
{
    foo( t );
}

struct S {};

void foo(S s) {}

int main()
{
    S s;
    tfoo(s);
}

此代码将因参数类型而编译S是一个类类型。它有一个关联的命名空间 - 全局命名空间 - 并且它添加(指定)该全局命名空间以进行依赖名称查找。此类 ADL 命名的命名空间可通过其相关查找来查看updated形式(从调用的角度来看)。这就是为什么lookup可以看到foo并成功完成。


当人们相信第二阶段所谓的“两阶段查找”应该可以看到一切这是在模板定义下面额外声明的,一直到实例化点(在本例中为调用点)。

不,第二阶段并没有看到一切。它可以看到额外的东西仅在与函数参数关联的命名空间中。所有其他命名空间都不会更新。它们看起来就像是从模板定义的角度观察到的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

定义模板后声明函数 的相关文章

随机推荐