2013-10-09 3 views
2

Отказ от ответственности: Я видел this question, и я точно спрашиваю, как decltype, предложенный в принятом ответе, может быть использован для этого.Как правильно вывести тип возврата для шаблона?

В основном я стараюсь (немного для удовольствия, немного для удобства и немного для учебной цели) для реализации небольших оберток для стандартных алгоритмов, которые упрощают их использование при применении ко всему контейнеру. Основная идея состоит в том, чтобы избавиться от .begin() и .end() и просто указать контейнер, на котором должен применяться алгоритм.

Затем я хотел бы узнать, возможно ли это (и не глупо, кстати) вывести возвращаемый тип моих оберток из самого типа возвращаемого стандартного алгоритма.

На данный момент, я попробовал следующее (для станд :: подсчет):

template<class Cnt, 
     class T> 
inline 
auto count(Cnt _cnt, const T& _val) -> decltype(std::count){} 

, но он дал мне ошибку во время компиляции:

Не удалось специализировать шаблон функции «» неизвестный тип «ragut :: Количество (НСТ, сопзЬ T &)»

Я полагал, что это не может быть достаточно, чтобы просто сказать decltype(std::count), и предположил, что это, как ked для более указанного аргумента:

decltype(std::count<std::iterator<std::input_iterator_tag,Cnt::value_type> >) 

, но это дало ту же ошибку.

Я хотел бы знать, если это на самом деле не глупо и возможно сделать это.

+1

Вы, вероятно, хотите, чтобы передать контейнер по константной ссылке. – MSalters

+0

@MSalters Правильно, хорошо, спасибо! – JBL

+1

Хорошо, что в C++ 14 мы, вероятно, сможем оставить тип возвращаемого возврата. Компилятор определит это из 'return std :: count (std :: begin (_cnt), std :: end (_cnt), _val);'. – MSalters

ответ

5

decltype(x) обозначает тип выражения x. Другими словами, вы пытаетесь создать функцию, возвращающую шаблон функции (в первом случае) или функцию (во втором случае). Это не сработает. Вы хотите, тип вызова к std::count, как это:

template<class Cnt, 
     class T> 
inline 
auto count(Cnt _cnt, const T& _val) 
    -> decltype(std::count(std::begin(_cnt), std::end(_cnt), _val))) 
{ } 
+1

Использование 'std :: begin (_cnt)' также позволяет ему вызываться с массивом. (Предполагая, что вы не скопируете '_cnt') – MSalters

+0

@MSalters Хорошая точка, обновленная. – Angew

+1

Хорошо прибил. Разница между типом указанной функции и ее возвращаемым типом. Таким образом, IIUC, 'decltype (std :: count)' фактически дает мне тип функции (т. Е. «Функция, которая принимает эти аргументы и возвращает это») вместо возвращаемого типа, правильно? – JBL

1

Он будет работать, если вы укажете правильные аргументы шаблона. В этом случае это будет <typename Cnt::const_iterator, typename Cnt::value_type>

+0

Нет, это не так. Это приведет к тому, что OP 'count' вернет тип функции. – Angew

+0

Справедливая точка, для этого вам действительно нужен класс ['function_traits'] (http://stackoverflow.com/a/7943765/15416). – MSalters

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