I want to have a templated friend function. However, I do not know how to make it works in the same way for no templated function. Here is a sample code
#include <iostream>
namespace ns{
struct Obj {
friend void foo(Obj){std::cout << "no problem" << std::endl;}
template<typename T>
friend void bar(Obj){std::cout << "problem" << std::endl;}
};
}
int main() {
ns::Obj obj;
foo(obj); // Compile
bar<int>(obj); // Not compile
return 0;
}
Before C++20, you need to teach the compiler that bar
is the name of a template so that it knows that <
starts a template argument list and is not the less-than operator:
template<char> void bar() = delete;
int main() {
ns::Obj obj;
foo(obj); // Compile
bar<int>(obj); // Now compiles too
return 0;
}
Note that all the bar
overload has to do is to be a function template. The signature doesn't matter as long as it's not so good as to interfere with the overload resolution; ()
is a good choice because by definition we are passing at least one argument, so a function template taking no parameters can never be viable.
Alternatively, you can redesign bar
to deduce T
from a tag argument:
template<class T>
struct type {};
namespace ns{
struct Obj {
// ...
template<typename T>
friend void bar(Obj, type<T>) { /* ... */ }
};
}
// ...
bar(obj, type<int>()); // OK
In C++20, the compiler will assume that bar
names a template when it sees the <
and name lookup finds nothing, so your code will just work.
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