Search code examples
c++templatesreturn-typefunction-templates

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?


Solution

  • 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"; }