Что такое decltype с двумя аргументами?
Отредактируйте, чтобы избежать путаницы:decltype
делаетне принять два аргумента. Посмотри ответы.
Следующие две структуры могут быть использованы для проверки существования функции-члена в типеT
во время компиляции:
// Non-templated helper struct:
struct _test_has_foo {
template<class T>
static auto test(T* p) -> decltype(p->foo(), std::true_type());
template<class>
static auto test(...) -> std::false_type;
};
// Templated actual struct:
template<class T>
struct has_foo : decltype(_test_has_foo::test<T>(0))
{};
Я думаю, что идея заключается в использовании SFINAE при проверке существования функции-члена, так что в случаеp->foo()
не действительна, только версия эллипсовtest
, который возвращаетstd::false_type
определено. В противном случае первый метод определен дляT*
и вернетсяstd::true_type
, Фактический «переключатель» происходит во втором классе, который наследуется от типа, возвращаемогоtest
, Это кажется умным и "легким" по сравнению с различнымиis_same
и тому подобное.
decltype
с двумя аргументами сначала выглядело удивительно для меня, так как я думал, что это просто получает тип выражения. Когда я увидел приведенный выше код, я подумал, что это что-то вроде «попробуйте скомпилировать выражения и всегда возвращать тип второго. Сбой, если выражения не скомпилируются» (поэтому скрыть эту специализацию; SFINAE).
Но:
Тогда я подумал, что мог бы использовать этот метод для написания любой проверки «является допустимым выражением», если она зависит от некоторого типаT
, Пример:
...
template<class T>
static auto test(T* p) -> decltype(bar(*p), std::true_type());
...
Это, как я думал, вернетstd::true_type
если и только еслиbar
определяется принятиеT
в качестве первого параметра (или еслиT
конвертируемый и т. д.), т. е. еслиbar(*p)
будет компилироваться, если это было написано в каком-то контексте, гдеp
определяется типаT*
.
Тем не менее, модификация выше оцениваетвсегда вstd::false_type
. Почему это? Я не хочу исправлять это каким-то сложным другим кодом. Я просто хочу знать, почему это не работает так, как я ожидал. Очевидно, чтоdecltype
с двумя аргументами работает не так, как я думал. Я не мог найти никакой документации; это везде объясняется только одним выражением.