C ++ явная специализация возвращаемого типа шаблона

Это продолжение этого (более общего) вопроса: предыдущий вопрос. Частичный ответ на данный вопрос дан здесь: частичный ответ на настоящий вопрос.

Я заинтересован в явной специализации возвращаемого типа на основе аргумента шаблона. Хотя приведенный выше ответ дает решение проблемы, я считаю, что существует более элегантный способ решения проблемы с использованием методов C ++ 11/14:

template<int N> auto getOutputPort2();
template<> auto getOutputPort2<0>();
template<> auto getOutputPort2<1>();

template<>
auto getOutputPort2<0>()
{
return std::unique_ptr<int>(new int(10));
}

template<>
auto getOutputPort2<1>()
{
return std::unique_ptr<string>(new string("asdf"));
}

Приведенный выше код компилируется и работает, как и ожидалось, используя gcc 4.8.3 (с флагом -std = c ++ 0x). Тем не менее, он выдает следующее предупреждение:

getOutputPort2 функция использует auto спецификатор типа без конечного возвращаемого типа.

Насколько я понимаю, это станет частью стандарта C ++ 14. Однако есть ли способ реализовать описанную выше функциональность в C ++ 11? Можно decltype использоваться здесь?


РЕДАКТИРОВАТЬ. Следуя комментариям ниже, я также хотел бы задать дополнительный вопрос. Является ли приведенный выше код действительным с точки зрения стандарта C ++ 14? Если нет, то почему нет?

0

Решение

Вы можете расширить идею вспомогательного шаблонного класса и поместить в него практически все. Это не совсем красиво для тех, кто должен написать специализацию, но это очень удобно для пользователя, который может просто позвонить f<0>, f<1>и т.д. Это не совсем необходимость decltype, но decltype действительно делает это немного легче писать.

template <int N>
struct f_impl;

template <int N>
decltype(f_impl<N>::impl()) f()
{ return f_impl<N>::impl(); }

template <> struct f_impl<0> {
static int impl() { return 1; }
};

template <> struct f_impl<1> {
static const char *impl() { return " Hello, world!"; }
};

int main() {
std::puts(f<1>() + f<0>());
}

Вы можете сделать его более управляемым с помощью макросов: вместо

template <> struct f_impl<1> {
static const char *impl() { return " Hello, world!"; }
};

Вы могли бы написать что-то вроде

#define DEFINE_F(N, Result)      \
template <> struct f_impl<N> { \
static Result impl();        \
};                             \
Result f_impl<N>::impl()

DEFINE_F(1, const char *) {
return " Hello, world!";
}

но я не уверен, что это лучше, чем просто писать f_impl (с лучшим именем) в полном объеме.

2

Другие решения


По вопросам рекламы [email protected]