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.
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 ofT
.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 linkingmain.o
andA.o
together, and all is fine. The disadvantage is that it will only work for the specific types (in this case, onlyint
) 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
Should Std::Common_Type Use Std::Decay
Function Already Defined Error in C++
Lifetime of Object Is Over Before Destructor Is Called
Conversion from Int** to Const Int**
When a Float Variable Goes Out of the Float Limits, What Happens
When to Use C++ Private Inheritance Over Composition
When How to Omit the Return Type in a C++11 Lambda
Implementing a Std::Vector Like Container Without Undefined Behavior
Vector<Unique_Ptr<A> > Using Initialization List
Lambdas and Capture by Reference Local Variables:Accessing After the Scope
Print Address of Virtual Member Function