I have
class ClassA {};
class ClassB {};
auto func_a() -> ClassA {
return ClassA(); // example implementation for illustration. in reality can be different. does not match the form of func_b
}
auto func_b() -> ClassB {
return ClassB(); // example implementation for illustration. in reality can be different. does not match the form of func_a
}
I want to be able to use the syntax
func<ClassA>() // instead of func_a()
func<ClassB>() // instead of func_b()
(this is as part of a bigger template)
but I don't know how to implement this template specialization for the function alias. Help? What is the syntax for this?
[Edit] The answers posted so far do not answer my question, so I'll edit my question to be more clear.
The actual definition of func_a and func_b is more complex than just "return Type();". Also they cannot be touched. So consider them to be
auto func_a() -> ClassA {
// unknown implementation. returns ClassA somehow
}
auto func_b() -> ClassB {
// unknown implementation. returns ClassB somehow
}
I cannot template the contents of func_a or func_b. I need the template for func<ClassA|ClassB> to be specialized for each one of the two and be able to select the correct one to call
CodePudding user response:
You might do something like (c 17):
template <typename T>
auto func()
{
if constexpr (std::is_same_v<T, ClassA>) {
return func_a();
} else {
return func_b();
}
}
Alternative for pre-C 17 is tag dispatching (which allows customization point):
// Utility class to allow to "pass" Type.
template <typename T> struct Tag{};
// Possibly in namespace details
auto func(Tag<ClassA>) { return func_a(); }
auto func(Tag<ClassB>) { return func_b(); }
template <typename T>
auto func() { return func(Tag<T>{}); }
CodePudding user response:
You can do it like this :
#include <iostream>
#include <type_traits>
class A
{
public:
void hi()
{
std::cout << "hi\n";
}
};
class B
{
public:
void boo()
{
std::cout << "boo\n";
}
};
template<typename type_t>
auto create()
{
// optional : if you only want to be able to create instances of A or B
// static_assert(std::is_same_v<A, type_t> || std::is_same_v<B, type_t>);
type_t object{};
return object;
}
int main()
{
auto a = create<A>();
auto b = create<B>();
a.hi();
b.boo();
return 0;
}