I have been trying to get the following code work from the book "The C++ Programming Language (4th Edition)" section "23.4.7 Friends" but could not succeed.

template<typename T> class Matrix;

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

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

template<typename T>
Vector<T> operator*(const Matrix<T>& m, const Vector<T>& v)
{
    Vector<T> r;
    // ... m.v[i] and v.v[i] for direct access to elements ...
    return r;
}

Here is a sample usage for the above API:

int main() {
    Matrix<int> lhs;
    Vector<int> rhs;
    Vector<int> r = lhs * rhs;

    return 0;
}

g++ with version:

g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3

gave the following output:

test.cpp:7: error: declaration of ‘operator*’ as non-function
test.cpp:7: error: expected ‘;’ before ‘<’ token
test.cpp:14: error: declaration of ‘operator*’ as non-function
test.cpp:14: error: expected ‘;’ before ‘<’ token

and clang with version:

Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix

gave the following output:

test2.cpp:7:19: error: friends can only be classes or functions
    friend Vector operator*<>(const Matrix<T>&, const Vector&);
                  ^
test2.cpp:7:28: error: expected ';' at end of declaration list
    friend Vector operator*<>(const Matrix<T>&, const Vector&);
                           ^
                       ;
test2.cpp:14:22: error: friends can only be classes or functions
    friend Vector<T> operator*<>(const Matrix&, const Vector<T>&);
                     ^
test2.cpp:14:31: error: expected ';' at end of declaration list
    friend Vector<T> operator*<>(const Matrix&, const Vector<T>&);
                              ^
                              ;
4 errors generated.

The book says:

The <> after the name of the firend function is needed to make clear that the friend is a template function.

I could not spot the problem in the code, can you?

有帮助吗?

解决方案

Yes, it's a bug in the book.

The function template must already be visible at that point, otherwise it cannot be instantiated to produce the overload you're trying to befriend.

So, moving the operator definitions above that of Vector (which in itself requires that we provide a forward declaration) solves the problem.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top