'Redefinition error when defining friend function inside class template [duplicate]
I am learning friend declarations in C++ using the books listed here. So after reading, to test my understanding of the concept, i wrote the following program whose output i am unable to understand:
template<typename T>
struct Name
{
friend void anotherFeed(int x)//anotherFeed is implicitly inline and its definition is generate only when we use this nonmember function so why are we getting error at instiantiation?
{
}
};
int main()
{
Name<int> s;
Name<double> p;//error here. My question is that this is instiantiation of the class template Name<double> and not a call to anotherFeed so why do we get error here?
}
The above program give the following error:
error: redefinition of ‘void anotherFeed(int)’
This is my current understanding:
- The friend non-member function
anotherFeed(int)is implicitly inline. - Even if
anotherFeed(int)isinline, we cannot define the same function(doesn't matter inline or not) in the same translation unit. - The definition of
anotherFeed(int)is generated only when we use/call this function just like for a nontemplate member function of a class template.
My question is that: Assuming that my understanding(the above 3 points) are correct, since i have not called/used anotherFeed so its definition should not be generated and we should not get the redefinition error at the time of creating an instance of the class template. Only when we call anotherFeed using those instances, we should get the redefinition error. So why do we get error at the time of creating class template's instance. Is there anything wrong in any of the above 3 points.
Summary
I read that the definitions for these functions(non template member functions and friend non template functions) are instantiated only when used. That is,
Name<int> s;
Name<double> p; //this should work in principle because this does not instantiate the definition of anotherFeed(int)
But this doesn't happen. Why/How?
Solution 1:[1]
The free function
friend void anotherFeed(int x){}
is not dependent on the template parameter, hence, there is only this one free function which is defined twice in your example. Make it a forward declaration only
template<typename T>
struct Name {
friend void anotherFeed(int x);
};
and define it outside the class definition
void anotherFeed(int x) {}
and all's well.
Solution 2:[2]
For a function template, its declaration can be instantiated without instantiating its definition.
This instantiates everything except the function body (more or less).
The declaration of your function is instantiated when the class is instantiated. When (and if) you actually call the function, its definition is instantiated.
I can't find the right standard quote, but apparently the compiler doesn't need to instantiate the definitions to reject the duplicate instantiated declarations.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ted Lyngmo |
| Solution 2 | HolyBlackCat |
