Укажите тип возвращаемого значения на основе другого аргумента шаблона

Я хотел бы указать тип возвращаемого значения моей шаблонной функции с помощью другого аргумента шаблона. Все это внутри класса.

В заголовочном файле:

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

В .cpp примерно так:

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

И я хотел бы иметь возможность использовать свою функцию вот так:

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"

Поэтому я хотел бы, чтобы моя функция могла параметризоваться одним целым числом шаблона (или каким-либо перечислением), а тип возвращаемого значения будет другим в зависимости от этого целого числа. Я не хочу, чтобы функция работала с любыми другими целочисленными аргументами, кроме указанных, например, здесь m.myfunc<4>() выдает ошибку компиляции.

Я хочу параметризовать свою функцию только одним аргументом шаблона, потому что m.myfunc<1, int>() будет работать, но я не хочу постоянно писать имя типа.

Я пробовал использовать типы автоматического возврата или другие шаблоны, но всегда получал ошибки компиляции. (Функция не найдена, внешние элементы не решены ...)

Возможно ли это каким-либо образом?


person Sipka    schedule 06.01.2015    source источник
comment
Специализации, подобные template<> int myfunc<1, int>(){ return 2; }, должны быть определены в файле заголовка, если вы хотите, чтобы они использовались вне этого .cpp файла.   -  person c-smile    schedule 07.01.2015
comment
По-прежнему выдает ошибку компиляции с could not deduce template argument for 'RT' при использовании как m.myfunc<1>();   -  person Sipka    schedule 07.01.2015
comment
@ c-smile Они должны быть объявлены в файле заголовка (хотя не уверен, что это необходимо). Определение не должно быть включено в несколько единиц перевода, иначе вы нарушите ODR (поскольку эти функции больше не являются шаблонами, не встроены и, похоже, не имеют внутренней связи).   -  person dyp    schedule 07.01.2015


Ответы (1)


Это то, что вы ищете?

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"; }
person Keith    schedule 06.01.2015
comment
Да! Большое тебе спасибо! Работает отлично. Мне нужно было определить структуры Typer внутри заголовка, но мне не нужно было объявлять специализации шаблона в заголовке, только в файле .cpp. - person Sipka; 07.01.2015