As a continuation to my last question, I'm now in the situation where I want to declare a function as a friend that depends on a mix of class template parameters (R
) AND additional template parameters (Cb
). How do I specify this correctly within class context? My naive approach doesn't seem to work:
#include <memory>
#include <future>
#include <cstdio>
template <typename Fn, typename R, typename... Args>
concept invocable_r = std::is_invocable_r<R, Fn, Args...>::value;
/* header.hpp */
template <typename T>
class entity;
template <typename R, invocable_r<R> Cb>
auto create_entity(Cb&& fn) -> std::shared_ptr<entity<R>>;
template <typename R>
struct entity
{
template <invocable_r<R> Cb>
entity(Cb&& fn)
: fn_{ std::move(fn) }
{}
// *************** Q ***************
// How to match this declaration to the outside declaration?
template<invocable_r<R> Cb>
friend auto create_entity<R>(Cb&& fn) -> std::shared_ptr<entity<R>>;
// *************** /Q ***************
std::packaged_task<R()> fn_;
};
/* impl.cpp */
template <typename R, invocable_r<R> Cb>
auto create_entity(Cb&& fn) -> std::shared_ptr<entity<R>> {
return std::make_shared<entity<R>>(std::forward<Cb>(fn));
}
int main()
{
create_entity<int>([]{ printf("Hello"); return 10; });
}
Error:
<source>:28:17: error: invalid use of template-id 'create_entity<R>' in declaration of primary template
28 | friend auto create_entity<R>(Cb&& fn) -> std::shared_ptr<entity<R>>;
|