C ++中的通用ostream问题

时间:2017-01-16 22:59:26

标签: c++ generics

我尝试做一个通用向量,但是当我编译它时会抛出这个错误:

Undefined symbols for architecture x86_64:
"operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Vec2<int> const&)", referenced from: 
referenced from:
  _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

请有人可以帮助我。这是代码:

#include <iostream>

template<typename T>
class Vec2 {
public:
    Vec2(T x, T y):x(x), y(y) {}
    friend std::ostream &operator <<(std::ostream &, const Vec2<T> &);
private:
    T x;
    T y;
};

template<typename T>
std::ostream &operator << (std::ostream &os, const Vec2<T> &vec) {

    os << "x: " << vec.x << ", y: " << vec.y << std::endl;

    return os;
}


int main(int argc, const char * argv[]) {

    Vec2<int> vi(3, 4);

    //Vec2<float> vf(3, 4);

    std::cout << vi;

    //std::cout << vf;

    return 0;
}

当我不使用模板时,代码可以正常工作。

2 个答案:

答案 0 :(得分:1)

我收到警告:

main.cpp:7:66: warning: friend declaration 'std::ostream& operator<<(std::ostream&, const Vec2<T>&)' declares a non-template function [-Wnon-template-friend]
     friend std::ostream &operator <<(std::ostream &, const Vec2 &);
                                                                  ^
main.cpp:7:66: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) 

您宣布非模板operator<<为好友。您应该声明您定义为朋友的函数模板:

template<typename U>
friend std::ostream &operator <<(std::ostream &, const Vec2<U> &);

答案 1 :(得分:0)

最简单的方法是声明函数inline

template<typename T>
class Vec2 {
public:
    Vec2(T x, T y):x(x), y(y) {}

    friend std::ostream& operator <<(std::ostream& os, const Vec2 &vec)
    {
        return os << "x: " << vec.x << ", y: " << vec.y << std::endl;
    }
private:
    T x;
    T y;
};

否则,您必须在:

之前声明模板功能
template <typename T> class Vec2;

template <typename T>
std::ostream& operator <<(std::ostream& os, const Vec2<T>& vec);

template<typename T>
class Vec2 {
public:
    Vec2(T x, T y):x(x), y(y) {}

#if 0
    // Here all operator << <U> are friend
    template <typename U>
    friend std::ostream& operator <<(std::ostream& os, const Vec2<U> &vec);
#else
    // Here only the matching specialization is friend
    friend std::ostream& operator << <>(std::ostream& os, const Vec2& vec);
#endif

private:
    T x;
    T y;
};

template <typename T>
std::ostream& operator <<(std::ostream& os, const Vec2<T>& vec)
{
    return os << "x: " << vec.x << ", y: " << vec.y << std::endl;
}

Demo