Undefined Symbol on a Template Operator Overloading Function

Undefined symbol on a template operator overloading function

The function template will be turned into an actual function at compile time, once the type represented by T (that is, int in your case) is actually known. However, this is not the case before main.cpp is compiled. At the time when A.cpp is compiled, the template function is not instantiated into an actual function, therefore the object file generated doesn't include the binary version of the function.

There are two ways to solve this.

  1. Include the function definition in your header file. That is, make

    template<class T>
    a::A& a::A::operator<<(T out) {
    std::cout << out;
    return (*this);
    }

    a part of the header file, and remove the function definition from the .cpp file.

    The effect of this is that any .cpp file that includes this header will be able to use any instantiation of the template, i.e. for any value of T.

  2. Alternatively, include an explicit template instantiation statement in A.cpp:

    template a::A& a::A::operator<<(int out);

    This will cause the compiler to actually instantiate the template when A.cpp is compiled, and to include the compiled function in the object file. Hence the linker can find it when linking main.o and A.o together, and all is fine. The disadvantage is that it will only work for the specific types (in this case, only int) that you provided explicit instantiations for.

Friend template function declared inside template class causing undefined symbol link error

The declaration inside the class as friend is non-template function, and the definition outside the class is template function, they don't match. And for overload resolution, non-template function will be selected prior to template function specialization, that's why undefined symbols link error occured.

You could change the declaration as template function:

template<typename X>
friend std::ostream& operator <<(std::ostream& out, const Node<X>& node);

LIVE

or define the function inside the class:

friend 
std::ostream& operator <<(std::ostream& out, const Node<T>& node) { return out << node.value(); }

LIVE

Undefined symbols for architecture x86_64 (I have found error, but I can not fix it.)

This is a well-known problem with template friends. The problem it that a compiler treats a friend declaration as a non-template, but it is a template. If you insist on the out-of-class definition of operator<<, you can do the following:

template<class T>
class Stack;

template<class T>
std::ostream& operator<<(std::ostream&, const Stack<T>&);

template<class T>
class Stack {
public:
friend std::ostream &operator<< <> (std::ostream&, const Stack<T>&);
};

template<class T>
std::ostream& operator<<(std::ostream&, const Stack<T>&) {
//...
}

In other words, you should first tell a compiler that friend operator<< is a template.

Demo

Friend template overloaded operator : unresolved external symbol

You should as well declare function signature inside rob namespace which it actually belongs:

namespace rob {
template <typename T>
class Stack {
friend std::ostream& operator<< (std::ostream& os, const Stack<T>& a);
};

template < typename T>
std::ostream& operator<< (std::ostream& os, const Stack<T>& a){
...
}

undefined reference to `operator(std::istream&, Complexint&) for template ComplexT

Friend functions are not members so they aren't implicitly templates. Declaration there suggests existence of non-template operator for instantiated type Complex<int>.
You may use

template<typename U> 
friend istream& operator>>(istream& input, Complex<U>& c1);

template<typename U>
friend ostream& operator<<(ostream& output, Complex<U>& c1);

Error when using += operator overload with templates Unresolved external symbol C++

Why not just define the function inside the class? That way, you could just use

MyClass<T>& operator +=(const T& rhs)
{
val += rhs;
return *this;
}

Note the use of += inside the implementation of operator+=. This works because the += is already implemented because it's the += for built in types. Normally, you should use val = val + rhs because you're implementing the += so it doesn't make sense to use it inside the implementation.

If you want to define it outside of class, it's going to be a bit more troublesome.

In your class, you need to declare

template<typename U>
friend MyClass<U>& operator +=(MyClass<U>& lhs, const U& rhs);

Then for function definition outside class

template<typename U>
MyClass<U>& operator +=(MyClass<U>& lhs, const U& rhs)
{
lhs.val += rhs;
return lhs;
}


Related Topics



Leave a reply



Submit