2015-06-02 2 views
2

В this answer создать тип признака:Как я могу использовать result_of Вместо decltype?

template<typename T> 
using to_string_t = decltype(to_string(declval<T>())); 

Это работает просто отлично, но я изначально установить, чтобы использовать result_of и теперь это irking мне, что я не могу понять, как это сделать.

Я пытаюсь заменить строку выше с чем-то вроде этого:

template<typename T> 
using to_string_t = result_of<to_string(T)>; 

Но я получаю ошибку компилятора вдоль линий:

ошибка C2275: «T»: недопустимый использование этого типа в качестве выражения
примечания: см декларирования «T»
ошибки C2974: «зОго :: result_of»: неверный аргумент шаблона для «_Fty», типа ожидается

Я пробовал несколько других входов до result_of без успеха, может ли кто-нибудь помочь мне понять, какие аргументы ждут здесь result_of?

ответ

8

Давайте исправим его. std::result_of ожидает только типы, его результат должен быть извлечен из его внутреннего идентификатора type, и вам нужно typename для доступа к указанному typedef, потому что это зависит от параметра шаблона.

template<typename T> 
using to_string_t = typename std::result_of<decltype(std::to_string)(T)>::type; 
        ^^^^^^^^    ^^^^^^^^     ^^^^^^ 

Или в C++ 14, вы можете оставить ::type и typename:

template<typename T> 
using to_string_t = std::result_of_t<decltype(std::to_string)(T)>; 
            ^^ 

Fine?

main.cpp:5:68: error: decltype cannot resolve address of overloaded function 

Право, std::to_string перегружен, поэтому нам нужно неоднозначность его отливка его одному из своих перегрузок.

template<typename T> 
using to_string_t = typename std::result_of<decltype(static_cast< 

Держать. Нам нужен его тип возврата, чтобы выразить тип назначения. Мы вернемся к нашей отправной точке.

std::result_of не может работать с перегруженными функциями, поскольку функция не имеет определенного типа, пока не будет разрешена перегрузка. decltype - единственное решение здесь, потому что оно делает применяет разрешение перегрузки.

Если вам интересно, как std::result_of может быть полезна, учитывая приведенное выше ограничение: оно используется для перегруженных функторов, то есть классов, которые несколько раз перегружают оператор (). Поскольку тип класса известен и не зависит от аргументов вызова, работает std::result_of.

... Но не должно std::to_string всегда возвращать std::string ??

+1

'decltype (decltype (станд :: to_string (declval ()) (declval ())' :) – bolov

+0

@bolov Отсутствует закрывающие скобки, но даже тогда вы звоните 'зЬй :: string' как функция ,Кроме того, это вряд ли избегает 'decltype' /' declval': p – Quentin

+0

sry: здесь это: 'std :: result_of_t ()) (std :: declval ()))> '(теперь тестировался, прошу про это). Но да, он использует decltype для получения результата 'to_string', чтобы создать тип, используемый в result_of, чтобы получить ... результат' to_string'. Но ... он использует 'result_of' :)) – bolov