Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specify return type based on other template argument

I'd like to specify my templated function's return type, by an other template argument. All of this inside a class.

In the header file:

class MyClass {
    template<int type, typename RT>
    RT myfunc();
};

In the .cpp something like this:

template<>
int MyClass::myfunc<1, int>() { return 2; }

template<>
double MyClass::myfunc<2, double>() { return 3.14; }

template<>
const char* MyClass::myfunc<3, const char*>() { return "some string"; }

And I would like to be able to use my function like this:

MyClass m;
int i = m.myfunc<1>(); // i will be 2
double pi = m.myfunc<2>(); // pi will be 3.14
const char* str = m.myfunc<3>(); // str == "some string"

So I would like my function to be able to parameterized by one template integer (or enumeration whatsoever), and the return type will be different, based on this integer. I don't want the function to work with any other integer arguments than the specified ones, for example here m.myfunc<4>() would give compile error.

I want to parameterize my function by one template argument only, because m.myfunc<1, int>() would be working, but I don't want to write the typename all the time.

I tried with auto return types, or templating other way around, but always got some compile errors. (Function not found, unresolved externals...)

Is this possible in any way?

like image 662
Sipka Avatar asked Jan 06 '15 22:01

Sipka


People also ask

How will you restrict the template for a specific datatype?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.

What is template argument deduction in C++?

Class Template Argument Deduction (CTAD) is a C++17 Core Language feature that reduces code verbosity. C++17's Standard Library also supports CTAD, so after upgrading your toolset, you can take advantage of this new feature when using STL types like std::pair and std::vector.

Can we use non-type parameters as argument templates?

A non-type template argument provided within a template argument list is an expression whose value can be determined at compile time. Such arguments must be constant expressions, addresses of functions or objects with external linkage, or addresses of static class members.

What is Typename in template?

In template definitions, typename provides a hint to the compiler that an unknown identifier is a type. In template parameter lists, it's used to specify a type parameter.


1 Answers

Is this what you seek?

template<int n>
struct Typer
{
};

template<>
struct Typer<1>
{
    typedef int Type;
};
template<>
struct Typer<2>
{
    typedef double Type;
};
template<>
struct Typer<3>
{
    typedef const char* Type;
};

class MyClass
{
public:
    template<int typeCode>
    typename Typer<typeCode>::Type myfunc();
};

template<> Typer<1>::Type MyClass::myfunc<1>(){ return 2; } 

template<> Typer<2>::Type MyClass::myfunc<2>() { return 3.14; }

template<> Typer<3>::Type MyClass::myfunc<3>() { return "some string"; }
like image 107
Keith Avatar answered Oct 13 '22 19:10

Keith