I get a linker error when I try to create an executable from the following code. I get the impression I need to place a few "typename
s" around or make some forward declarations; I've tried a few combinations but none worked.
template<typename T>
class enabled
{
private:
T type_;
friend const T& typeof(const enabled<T>& obj); // Offending line
};
template<typename T>
const T& typeof(const enabled<T>& obj) {
return obj.type_;
}
int main()
{
enabled<std::string> en;
std::cout << typeof(en);
std::cin.clear(), std::cin.get();
return 0;
}
1>main.obj : error LNK2001: unresolved external symbol "class std::string const& __cdecl typeof(class enabled<class std::string> const&)"
By forward declaring and specifying that the function is templated
template<typename T> class enabled;
template<typename T>
const T& typeof(const enabled<T>& obj) {
return obj.type_;
}
template<typename T>
class enabled
{
private:
T type_;
friend const T& typeof<>(const enabled<T>& obj);
};
The problem is that the function which is a friend of the class, is not a function template, while the function you actually have defined is a function template.
All that you need to do is make the friend a function template as:
template<typename T>
class enabled
{
private:
T type_;
template<typename U> //<-------------------------------note this
friend const U& typeof_(const enabled<U>& obj); //use U
};
Now this compiles just fine : http://www.ideone.com/VJnck
But it makes all instantiations of typeof_<U>
friend of all instantiations of enabled<T>
, which means typeof_<int>
is a friend of enabled<T>
for all possible value of T
, and vice versa.
So a better solution is to make the function non-template and define it inside the class as:
template<typename T>
class enabled
{
private:
T type_;
friend const T& typeof_(const enabled<T>& obj)
{
return obj.type_;
}
};
Demo : http://www.ideone.com/Rd7Yk
Note that I replaced typeof
with typeof_
, as GCC has an extension with name typeof
, and so it was giving error on ideone (as I can't turnoff extensions).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With