1

I have written a simple operator overloaded function, which is working fine if I define it within the class (block commented), but getting error, if define outside the class. Any idea where is the mistake?

#include<iostream>

using namespace std;


template<class T>
class vector{
    
    int d;
public:
    vector(){
        d = 0;
    }
    vector(T data){
        d = data;
    }
    
    friend void operator << (vector &v, T data);
    /*{
        cout << data << endl;
    }*/
    
};

template<class T>
void operator << (vector<T> &v, T data){
    
    cout <<  data;
}


int main(){
    
    vector<int> v1;
    v1 << 10;
    
    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Vivek Roy
  • 21
  • 1
  • Maybe the compiler can not distinguish `std::vector` and your `vector` classes? – vahancho Jul 20 '20 at 12:29
  • 3
    `using namespace std;` — don't do this. Even if its not likely, `` can include ``. – Daniel Langr Jul 20 '20 at 12:30
  • What error are you getting? Please [edit] your question to be specific. I got a warning, a notice, and an undefined reference. https://ideone.com/cXFacq If you read them carefully, you might notice what’s wrong. – Melebius Jul 20 '20 at 12:32
  • 1
    [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) It will bite you very soon with a name like `vector`. Don't use it. – Yksisarvinen Jul 20 '20 at 12:33

3 Answers3

3

This friend function declaration within the class template definition

friend void operator << (vector &v, T data);

is not a template function (though it is a templated entity if it is defined within the class).

On the other hand, this declaration outside the class template definition

template<class T>
void operator << (vector<T> &v, T data){
    
    cout <<  data;
}

defines a template function.

Either define the friend function in the class definition. And in this case the compiler will generate the definition of the function for each used specialization of the class template. Or for each used class specialization you have to define (provide) a separate non-template friend function explicitly yourself.

Here is a demonstrative program

#include<iostream>

template<class T>
class vector{
    
    int d;
public:
    vector(){
        d = 0;
    }
    vector(T data){
        d = data;
    }
    
    friend void operator << (vector &v, T data);
    /*{
        cout << data << endl;
    }*/
    
};

template<class T>
void operator << (vector<T> &v, T data)
{    
    std::cout <<  data;
}

void operator << (vector<int> &v, int data)
{    
    std::cout <<  data;
}

int main()
{
    
    vector<int> v1;
    v1 << 10;
    
    return 0;
}

The program output is

10

In the program there are two overloaded functions operator <<. The first one is a friend non-template function declared in the class definition and the second one is a template function that is not a friend function of the class. For the class specialization vector<int> used in main you have to provide the non-template friend function definition outside the class.

Or you could define the friend function within the class.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

Problem is how to friend a template to other template.

Without friendship your code works (you do no access private parts).

To fix it you have to friend a template and not to a regular function. Since function you are defining is a template friendship statement have to express that.


template<class T>
class vector{
    
    int d;
public:
    ...

    template<typename U>
    friend void operator<<(vector<U> &v, U data);
};

https://godbolt.org/z/oxcojb

Offtopic:
Personally I avoid friendships (I do not remember to ever use it in my code). Your code I would do like this.

Marek R
  • 32,568
  • 6
  • 55
  • 140
  • Yes, it solves my problem. You are right, not able to make a template function to another template. Thanks. – Vivek Roy Jul 21 '20 at 13:32
-2

if you are using namespace std and then defining a class called vector, which is a name from the std namespace, the compiler will not know which one to use and this will result in undefined behaviour, or so I think.

also, you are getting the error because you need to define that function inside the class because you are using a template.

Adrian Costin
  • 418
  • 3
  • 12
  • 3
    While the first part is in general true, it's not the direct issue here. It would result in a different message (something about "ambiguous overload"). And there is no rule that templates must be defined inline, the problem is that `friend` declaration doesn't get `template` from the class it's declared in. GCC has a nice, elaborate warning on the issue: https://wandbox.org/permlink/6t8KV2rCm8wCrHcK – Yksisarvinen Jul 20 '20 at 12:42