3

I'm trying to overload the "<<" operator in order to print a class that has been declared inside a template class. I've looked for a solution but I haven't really found any examples similar to my own. The following code illustrates my problem:

#include <iostream>

template<class T>
class main_class
{
public:
    class dependent_class
    {
    public:
        dependent_class() : val(0) { }
        template<class T>
        friend std::ostream& operator<<(std::ostream&, const dependent_class&);
    protected:
        int val;
    };
};

template<class T>
std::ostream& operator<<(std::ostream& out, const typename main_class<T>::dependent_class& v)
{
    return out << v.val;
}

int main(int argc, char* argv[])
{
    main_class<int>::dependent_class v;
    std::cout << v; // error: no operator "<<" matches these operands
    //      operand types are: std::ostream << main_class<int>::dependent_class

    return 0;
}
asmmo
  • 6,922
  • 1
  • 11
  • 25
  • 1
    You're declaring a friend function that is a template of a template, but the global function you declare it is just a function that takes a templated type as a parameter. You probably just need to remove the `template` from in front of the `friend`. – 1201ProgramAlarm May 24 '20 at 04:18

2 Answers2

1
#include <iostream>

template<class T>
class main_class
{
public:
    class dependent_class
    {
    public:
        dependent_class() : val(0) { }

        friend std::ostream& operator<<(std::ostream& out, const main_class<T>::dependent_class& v){
            return out << v.val;
        }
    protected:
        int val;
    };
};



int main(int argc, char* argv[])
{
    main_class<int>::dependent_class v;
    std::cout << v; // error: no operator "<<" matches these operands
    //      operand types are: std::ostream << main_class<int>::dependent_class

    return 0;
}

You were having errors in your code.

In the dependent_class you are using the template twice which shadows the template parameter.

 class dependent_class
    {
    public:
        dependent_class() : val(0) { }
        template<class T> //here
        friend std::ostream& operator<<(std::ostream&, const dependent_class&);
    protected:
        int val;
    };
  • 2
    Adding an explanation of what the errors are, and how your code fixes them, would make the answer more helpful. Also, you should leave out the large parts of the original code that have not changed - just leave enough for context (if necessary). – 1201ProgramAlarm May 24 '20 at 04:19
  • Removing the `template` from before the friend declaration resolves my original error but results in a different error. When the `template` is removed, I get a linker error in Visual Studio (LNK2019: "unresolved external symbol referenced in function _main") – guyoverthere522 May 24 '20 at 05:12
  • @guyoverthere522 you also need to move function definition inside the class as written in the answer – Alexey Andronov May 24 '20 at 05:23
  • While the resulting code is correct, the provided explanations for the causes are not. Sure, overshadowing of template parameter T is having place but the core issue is ["non-deducible context"](https://stackoverflow.com/q/6060824/597607) in free template function. See awesome answers to [this question](https://stackoverflow.com/questions/10651161/overloading-operator-cannot-bind-lvalue-to-stdbasic-ostreamchar/10651752) if you want to learn more – Alexey Andronov May 24 '20 at 05:36
0

Move the definition of operator<< to the scope of dependent_class and remove template<class T> before the declaration:

#include <iostream>

template<class T>
class main_class
{
public:
    class dependent_class
    {
    public:
        dependent_class() : val(0) { }
        friend std::ostream& operator<<(std::ostream& out, const dependent_class& v)
        {
            return out << v.val;
        }

    protected:
        int val;
    };
};




int main(int argc, char* argv[])
{
    main_class<int>::dependent_class v;
    std::cout << v; // error: no operator "<<" matches these operands
    //      operand types are: std::ostream << main_class<int>::dependent_class

    return 0;
}
Amal K
  • 4,359
  • 2
  • 22
  • 44