pree
pree

Reputation: 2357

C++ Template specialization with class as return type and enum as parameter

I don't have a lot of experience using templates but I'm trying to do template specialization based on enums with a function which returns different classes. Below is the sample code (or rather what I'm trying to accomplish):

class Foo {
  // member variables
};
class Cat {
  // member variables
};

enum MyType{ A, B, C};

// Header file
template<class T, MyType U> std_shared_ptr<T> process();

// cpp file / implementation
template<> std_shared_ptr<Foo> process<Foo, A>()
{
}

template<> std_shared_ptr<Cat> process<Cat, C>();
{
}

Can someone help me in figuring out what I'm missing here or doing wrong? I tried searching it and found some solutions for handling enum types (Template specialization for enum), however, can't figure out how to put it together with a template return type in a function.

EDIT: What I'm trying do here is to do template specialization based on enum type as argument to a function. And the same function returns a template class as well. So the function has two templates here: T (return param) and U (input param which is an enum). Is it possible to do so?

EDIT: Modified the above sample for the right behavior.

Upvotes: 2

Views: 1197

Answers (1)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275350

You cannot partially specialize template functions.

The value, not the type, of a function parameter cannot change the type of the return value. The value of a non-type template parameter can change the type of the return value, but that is passed within the <> and must be compile-time determined, not within the ()s.

Tags may help.

template<MyType X>
using my_type_tag_t=std::integral_constant<MyType, X>;
template<MyType X>
constexpr my_type_tag_t<X> my_type_tag = {};

template<class T>struct tag_t{using type=T;};
template<class Tag>using type=typename Tag::type;

template<MyType>
struct my_type_map;
template<>
struct my_type_map<MyType::A>:tag<Foo>{};
template<>
struct my_type_map<MyType::B>:tag<Cat>{};

then:

template<MyType X>
std::shared_ptr<type<my_type_map<X>>>
process( my_type_tag_t<X> );

where you call process( my_type_tag<A> ) to get a shared_ptr<Foo> out of it.

Implementations look like:

template<>
std::shared_ptr<Foo>
process( my_type_tag_t<MyType::A> ) {
  // blah
}

still inelegant, and probably doesn't solve your problem, but it is close to your described solution.

Upvotes: 2

Related Questions