c++ - 什么时候必须声明模板中使用的函数?

标签 c++ templates forward-declaration

我(可能)有一个简单的问题。 什么时候必须声明模板中使用的函数? 打印出以下代码(使用 gcc >=4.1):

init my A object

no init

使用 gcc 4.0 打印出以下代码:

init my A object

init my string object

#include <iostream>
#include <string>

template<typename T>
void init(T& t){
        std::cout << "no init" << std::endl;
}

// void init(std::string& t);

template <typename T>
void doSomething(T& t){
        init(t);
        // do some further stuff
}

void init(std::string& t){
        std::cout << "init my string object" << std::endl;
}


class A{

};

void init(A& t){
        std::cout << "init my A object" << std::endl;
}

int main(){
        A a;
        doSomething(a);
        std::string s("test");
        doSomething(s);
        return 0;
}

std::string 和 A 的用法有什么区别? 难道不应该有同样的行为吗?

通过附加的前向声明,它可以正常工作, 但我什么时候需要它?

干杯, CSpille

最佳答案

仅使用参数相关查找(在与函数参数关联的命名空间中查找函数)来查找实例化点处的函数。正常查找仅在模板定义处完成。

因此,对于 std::string 来说,只有通用的 init 函数模板可见并被调用,因为命名空间 std< 中没有特定的函数模板。/。对于A,更具体的函数可以在A的全局命名空间中找到。

如果您向前声明字符串特定函数出现在 doSomething 之前,则正常的非限定查找会在定义处找到它并稍后使用它。

如果您按如下方式调用 init,它将禁止参数相关查找,因此也会使用 A 的通用模板。

template <typename T>
void doSomething(T& t){
    (init)(t);
    // won't do ADL
}

(作为旁节点:在这种情况下,不仅在实例化时禁止参数依赖查找,而且 init 首先不会是依赖名称 - 仅是非括号和不合格的函数名称是相关的。因此,无论如何,仅在定义时进行非 ADL 查找,并且在实例化时不会进行任何查找,即使存在与在那里进行的 ADL 不同的形式。)

关于c++ - 什么时候必须声明模板中使用的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3178478/

相关文章:

c++ - 在 C++ 中转发声明枚举

c++ - 强制在 Mac 上对 C++ 代码使用前向声明(使用 Xcode)

c++ - 在主程序中包含头文件和源文件之间的混淆

c++ - 从定义变量的程序之外的程序中检索 C 全局变量

c++ - 使用模板的 undefined symbol

c++ - 编译错误 C++ : could not deduce template argument for 'T'

c++ - 从C++ dll调用Go dll

c++ - 宏和内联函数在执行速度方面有何区别?

c++ - 私有(private)类型的模板特化

delphi - delphi 中程序的前向声明