2014-10-16 3 views
0

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

template<typename Data> 
auto foo(const Data& d) -> 
    typename std::decay<decltype(reinterpret_cast<const Data*>(0)->operator()(0, 0))>::type 
{ 
    typedef typename std::decay<decltype(reinterpret_cast<const Data*>(0)->operator()(0, 0))>::type return_t; 
    ... 
} 

В то время как это работает, это некрасиво и не совсем очевидно, что я хочу от беглого взгляда. Есть ли более читаемый, менее «хакерский» способ получить «возвращаемый тип вызова этого метода в аргументе шаблона»?

+0

Вы уверены, что хотите разложить тип, или он может быть таким же, как и для 'operator()'? –

+0

В этом случае я хочу разложить его. Даже если 'operator()' возвращает 'const T &', я хочу вернуть 'T', потому что я создаю новые значения путем интерполяции в этом конкретном случае. –

+0

может 'Data' быть функцией, или он должен быть классом с' operator() '? –

ответ

1

Без псевдонимов шаблонов (C++ 11):

template <typename Data> 
auto foo(const Data& d) -> typename std::decay<decltype(d(0, 0))>::type 
{ 
    return {}; 
} 

или:

template <typename Data 
     , typename return_r = typename std::decay< 
       typename std::result_of<const Data(int, int)>::type 
      >::type> 
return_r foo(const Data& d) 
{ 
    return {}; 
} 

С псевдонимами шаблонов (C++ 14 или написанного вручную):

template <typename Data> 
auto foo(const Data& d) -> std::decay_t<decltype(d(0, 0))> 
{ 
    return {}; 
} 

или:

template <typename Data 
     , typename return_r = std::decay_t<std::result_of_t<const Data(int, int)>>> 
return_r foo(const Data& d) 
{ 
    return {}; 
} 
+0

Первый пример отлично работает. Однако вторая причина проблемы, потому что некоторые «данные» определяют их оператор как «operator() (unsigned int, unsigned int)», тогда совпадение не выполняется. * ugh * Но первая лучше всего нагружает: D –

Смежные вопросы