Как я могу использовать result_of вместо decltype?
В этом ответе я создаю черту типа:
template<typename T>
using to_string_t = decltype(to_string(declval<T>()));
Это работает просто отлично, но я изначально намеревался использовать result_of
и теперь меня раздражает, что я не могу понять, как это сделать.
Я пытаюсь заменить строку выше чем-то вроде этого:
template<typename T>
using to_string_t = result_of<to_string(T)>;
Но я получаю ошибку компилятора в соответствии с:
ошибка C2275: 'T': незаконное использование этого типа в качестве выражения
примечание: см. объявление "Т"
ошибка C2974: "std::result_of": неверный аргумент шаблона для "_Fty", тип ожидается
Я пробовал несколько других входов в result_of
без успеха, может кто-нибудь помочь мне понять, что аргументы result_of
ожидает здесь?
1 ответ
Давайте исправим это. std::result_of
ожидает только типы, его результат должен быть извлечен из его type
внутренний typedef, и вам нужно 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)>;
^^
Хорошо?
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
??