Class template friend operators

The code below doesn't compile.
I would like to understand why and how to fix it.
Thank you.

Two things to clear up:
1) I know x is going to be garbage.
2) I know that it doesn't help that I used the same type name label ElementType.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <ostream>

template <typename ElementType>
class Example
{
private:
    ElementType x;

template <typename ElementType>
friend std::ostream & operator << (std::ostream &, const Example &);
};

template <typename ElementType>
std::ostream & operator << (std::ostream &os, const Example<ElementType> &e)
{
    os << e.x << '\n';
    return os;
}

int main()
{
    Example<int> e;
    std::cout << e << std::endl;
}


class_template_friends.cpp:10:11: error: declaration of 'class ElementType'
 template <typename ElementType>
           ^
class_template_friends.cpp:4:11: error:  shadows template parm 'class ElementType'
 template <typename ElementType>
           ^
class_template_friends.cpp: In instantiation of 'std::ostream& operator<<(std::ostream&, const Example<ElementType>&) [with ElementType = int; std::ostream = std::basic_ostream<char>]':
class_template_friends.cpp:24:18:   required from here
class_template_friends.cpp:8:17: error: 'int Example<int>::x' is private
     ElementType x;
                 ^
class_template_friends.cpp:17:8: error: within this context
     os << e.x << '\n';
        ^
I saw a few threads about problems with friend templates when I searched the forum. But I remember seeing this one a little while back:
http://www.cplusplus.com/forum/general/110628/

The parashift page that Cubbi linked to also provides an explanation as to why friend function template prototypes can be an issue.
Last edited on
Thanks. The final version below works.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <ostream>

template <typename ElementType>
class Example
{
private:
    ElementType x;

template <typename Temp>
friend std::ostream & operator << (std::ostream &, const Example<Temp> &);
};

template <typename ElementType>
std::ostream & operator << (std::ostream &os, const Example<ElementType> &e)
{
    os << e.x << '\n';
    return os;
}

int main()
{
    Example<int> e;
    std::cout << e << std::endl;
}

The error tells you what's wrong: On line 10 you have a second template with the same name ElementType. Remove that. It should be fine for that error.

write the implementation of the operator<< inside the class. The reason is that only Example<int> is instantiated. For whatever reason the compiler sees the declaration of operator<< but not the implementation when it's outside the class and not used inside.
Last edited on
Topic archived. No new replies allowed.