模板中的运算符<< class;带命名空间;

operator<< in template class; with namespace;

我在链接以下代码段时遇到问题。链接器找不到友元模板函数的实现。 知道为什么找不到它吗?

声明

// XY.hpp
namespace xxx
{

template<typename T> class XY;

template<typename T>
std::ostream& operator<<(std::ostream&, const XY<T>&);

template<typename T>
class XY
{
public:
    // ... constructors, destructor, getters, setters, etc
    friend      std::ostream& operator<< <T>(std::ostream&, const XY<T>&);

private:
    //...

};

} /* namespace xxx*/

定义

// XY.cpp
#include "XY.hpp"

namespace xxx
{

template<typename T>
std::ostream& operator<<(std::ostream& os, const XY<T>& rhs)
{
    // ...
    return os;
}
} /* namespace xxx */

用法

// main.cpp
#include "XY.hpp"
#include <iostream>

using namespace std;
using namespace xxx;

int main() {
    XY<uint16_t> xy;
    cout << xy;

    return 0;
}

链接器 returns 错误:undefined reference to 'std::ostream& xxx::operator<< <unsigned short>(std::ostream&, xxx::XY<unsigned short> const&)'

链接 g++ -o "XXX" ./src/XY.o ./src/main.o
版本:gcc.EXE (GCC) 6.3.0

定义XY使用operator<<时,没有定义operator<<。您在源文件中定义了一个模板,但是 uint16_t 没有此模板的实例化。您可以通过源文件末尾的显式模板实例化来绕过。

template std::ostream& operator<< <uint16_t> (std::ostream& os, const XY<uint16_t>& rhs);

但我认为这不是一个好主意。你最好在头文件中声明和定义模板。