gpt4 book ai didi

c++ - 为什么那个模板函数不能编译?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:27:42 25 4
gpt4 key购买 nike

这是一个非常短的代码段,无法使用 g++ 4.7.1 进行编译(顺便说一句,它也无法使用 gcc 4.6.3 进行编译)。

#include <iostream>

template<typename T>
struct Foo
{
template<typename U>
friend std::ostream& operator<<(Foo&, U&);
};

template<typename T, typename U>
std::ostream& operator<<(Foo<T> foo, U& u)
{
std::cout << u;
return std::cout;
}

int main()
{
Foo<int> f;
f << "bar";
return 0;
}

这就是 gcc 4.7.1 输出的内容(4.6.3 说的几乎相同)。

/tmp/ccNWJW6X.o: In function main': main.cpp:(.text+0x15): undefined
reference to
std::basic_ostream >& operator<< (Foo&, char const (&) [4])' collect2: ld returned 1 exit status

谁能解释一下原因?

编辑

我也试过用 clang 3.1,它说的完全一样。

最佳答案

与模板的友元可能有点复杂......让我们看看你的代码做了什么:

template<typename T>
struct Foo {
template<typename U>
friend std::ostream& operator<<(Foo&, U&); // [1]
};
template<typename T, typename U>
std::ostream& operator<<(Foo<T> foo, U& u) { // [2]
std::cout << u;
return std::cout;
}

当您使用类型实例化 Foo 时,例如 int [1] 中的友元声明声明了一个模板函数:

template <typename U>
std::ostream& operator<<(Foo<int>&,U&);

但是该函数在任何地方都不存在,您在 [2] 中提供的是一个带有两个参数的模板:

template<typename T, typename U>
std::ostream& operator<<(Foo<T> foo, U& u);

重点是友元声明是在实例化模板的同时处理的,此时Foo代表的是当前实例化得到的类型。

对于你想做的事情有不同的选择,最简单的是将好友声明更改为:

template<typename W, typename U>
friend std::ostream& operator<<(Foo<W> foo, U& u);

它声明了一个带有两个参数的模板(WU 在这里都是未绑定(bind)的),并在命名空间级别匹配您的定义。

另一种选择是在类模板定义中定义友元函数,在这种情况下您可以保持原始签名。有关不同替代方案的更多信息,请查看其他 answer

关于c++ - 为什么那个模板函数不能编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12310933/

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