notaorb
notaorb

Reputation: 2190

Problem compiling a template friend example from Stroustrup's C++

Does anyone know why this will not compile and how to correct it? I'm trying to use friends and templates. I'm using this code from Stroustrup C++ 4th Ed Page 682-683.

Thanks

#include <iostream>
using namespace std;

template<typename T>
class Matrix;

template<typename T>
class Vector
{
    T v[4];
public:
    friend Vector operator*<>(const Matrix<T>&, const Vector&);
};

template<typename T>
class Matrix 
{
    Vector<T> v[4];
public:
    friend Vector<T> operator*<>(const Matrix&, const Vector<T>&);
};

template<typename T>
Vector<T> operator*(const Matrix<T>& m, const Vector<T>& v)
{
    Vector<T> r;
}

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

Compilation:

clang++ -std=c++11 -pedantic -Wall -g test165.cc && ./a.out
test165.cc:12:19: error: friends can only be classes or functions
    friend Vector operator*<>(const Matrix<T>&, const Vector&);
                  ^
test165.cc:12:28: error: expected ';' at end of declaration list
    friend Vector operator*<>(const Matrix<T>&, const Vector&);
                           ^
                           ;
test165.cc:19:22: error: friends can only be classes or functions
    friend Vector<T> operator*<>(const Matrix&, const Vector<T>&);
                     ^
test165.cc:19:31: error: expected ';' at end of declaration list
    friend Vector<T> operator*<>(const Matrix&, const Vector<T>&);
                              ^

Upvotes: 2

Views: 38

Answers (1)

songyuanyao
songyuanyao

Reputation: 172984

The friend declaration refers to the instantiation of template operator* (i.e. operator*<T>), but the template doesn't exist (has not been declared) and then cause the error.

You need to declare the operator template in advance.

E.g.

template<typename T>
class Matrix;

template<typename T>
class Vector;

// declaration
template<typename T>
Vector<T> operator*(const Matrix<T>& m, const Vector<T>& v);

template<typename T>
class Vector
{
    T v[4];
public:
    friend Vector operator*<>(const Matrix<T>&, const Vector&);
};

template<typename T>
class Matrix 
{
    Vector<T> v[4];
public:
    friend Vector<T> operator*<>(const Matrix&, const Vector<T>&);
};

// definition
template<typename T>
Vector<T> operator*(const Matrix<T>& m, const Vector<T>& v)
{
    Vector<T> r;
}

Upvotes: 2

Related Questions