ataraxis
ataraxis

Reputation: 1572

Is there a way to "translate" types in C++?

Depending on the type of a variable I would like to call a templated function (which is given). The problem is, the expected types for the template won't fit directly.

Example: If the type of my variable is int, then I would like to call the function foo<classA>(). If the type is double I would like to call foo<classB>() and so on...

Until now I have called the function inside a switch case.

My Question is: Is there a way to "translate" types? Sth. like a function to which I pass int and I will get classA back? This way I could simply call the function like this: foo<translate_type(variable)> foo()

What I tried is, as I wrote, a switch case. Another possibility might be a templated function around the template. One which is accepting e.g. int and is then calling the right function foo<classA>(). Furthermore I would like to avoid Macros.

Maybe there is a better way in modern C++? One that is a bit better maintainable without using cases.

Upvotes: 1

Views: 280

Answers (2)

einpoklum
einpoklum

Reputation: 131533

My Question is: Is there a way to "translate" types?

Of course. C++ has had this since forever.

template <typename T>
struct my_translator;

template<>
struct my_translator<int> {
    using type = classA;
}

And now you can write:

typename my_translator<int>::type

and get classA. This works with C++98 even, I think. It's basically how all of those type traits in the standard library are implemented, like std::make_unsigned.

If you use C++11 or later, you can make a shortcut beyond the above trait:

template <typename T>
using my_translator_t = typename my_translator<T>::type;

and then, you only need to use my_translator_t<int> to get classA.

Upvotes: 4

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275385

template<class T>
struct type_trait{using type=T;}; // can leave the type part out, and even the body, for errors/diagnostics
template<class T>
using type_trait_t=typename type_trait<T>::type;

template<>
struct type_trait<int>{using type=Foo;};
template<>
struct type_trait<double>{using type=Bar;};

template<class T> void func(){}

func<type_trait_t<int>>(); // calls func<Foo>
func<type_trait_t<double>>(); // calls func<Bar>
func<type_trait_t<char>>(); // calls func<char>

I think this is what you are looking for?

Upvotes: 5

Related Questions