Что такое 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());
...

http://ideone.com/dJkLPF

Это, как я думал, вернетstd::true_type если и только еслиbar определяется принятиеT в качестве первого параметра (или еслиT конвертируемый и т. д.), т. е. еслиbar(*p) будет компилироваться, если это было написано в каком-то контексте, гдеp определяется типаT*.

Тем не менее, модификация выше оцениваетвсегда вstd::false_type. Почему это? Я не хочу исправлять это каким-то сложным другим кодом. Я просто хочу знать, почему это не работает так, как я ожидал. Очевидно, чтоdecltype с двумя аргументами работает не так, как я думал. Я не мог найти никакой документации; это везде объясняется только одним выражением.

Ответы на вопрос(0)

Ваш ответ на вопрос