I have the following class:
class Inject{
template<template <class> class Daemon>
RETURNTYPE register_inj();
}
There are a number of implementation to this template function where the template arguments are explicitly specified one example is returning a class ServiceA
which has one template argument that in this case is chosen to be class CacheA
. The rule is that the template function will always have one template argument, but that template argument can have multiple template template arguments. E.g. ServiceB<typename A, typename B>
For serviceA
the funtion template is implemented to:
template<>
auto register_inj<ServiceA<CacheA>>
{ impl... }
My question is what should RETURNTYPE
be set to in the header file?
CodePudding user response:
I believe this question mixes two separate things.
The number of template arguments of the function template argument
Daemon
has nothing to with the return type. In fact, your specialisation forServiceA
indicates that you are not even asking for a template template argument.ServiceA<CacheA>
is not a template - it is a normal type (which happens to be an instantiation of a template). Your function should therefore simply be declared astemplate <class Daemon> RETURNTYPE register_inj()
. It will then work withServiceA<CacheA>
as well as withServiceB<CacheB,ResolverB>
(both of them are just types). You only need a template template parameter if you are instantiating that template within the body of your function.In the header, the function return type could simply be declared to
auto
. That effectively declares the function to have a deduced return type. However, you won't be able to use that function until it is defined (every call-site needs to know the return type of that function). You will therefore have to inline the function definition into your header as-well. If you want to avoid that, you will have to explicitly write the return type using meta-programming techniques, e.g. as follows:
// you need at least a forward definition of your services here,
// as well as the return types
template <typename Cache>
class ServiceA<Cache>;
template <typename Cache, typename Resolver>
class ServiceB<Cache,Resolver>;
class ServiceARegisterResult;
template <typename Resolver>
class ServiceBRegisterResult<Resolver>;
namespace detail {
template <typename Service>
struct register_inj_return_type {};
template <typename Cache>
struct register_inj_return_type<ServiceA<Cache>> : {
using type = ServiceARegisterResult;
};
template <typename Cache, typename Resolver>
struct register_inj_return_type<ServiceB<Cache,Resolver>> : {
using type = ServiceBRegisterResult<Resolver>;
};
}
class Inject{
template<class Daemon>
typename detail::register_inj_return_type<Daemon>::type
register_inj();
};