Подтвердить что ты не робот

SFINAE + sizeof = определение, если выражение компилируется

Я только выяснил, как проверить, предоставлен ли operator<< для типа.

template<class T> T& lvalue_of_type();
template<class T> T  rvalue_of_type();

template<class T>
struct is_printable
{
    template<class U> static char test(char(*)[sizeof(
        lvalue_of_type<std::ostream>() << rvalue_of_type<U>()
    )]);
    template<class U> static long test(...);

    enum { value = 1 == sizeof test<T>(0) };
    typedef boost::integral_constant<bool, value> type;
};

Является ли этот трюк известным, или я только что выиграл метапрограммирование Нобелевской премии?;)

EDIT: я сделал код более понятным и легче адаптируемым с двумя объявлениями шаблонов глобальных функций lvalue_of_type и rvalue_of_type.

4b9b3361

Ответ 1

Это хорошо известная техника, я боюсь: -)

Использование вызова функции в операторе sizeof дает указание компилятору, конечно же, выполнять дедукцию аргументов и соответствие функций во время компиляции. Кроме того, с помощью функции шаблона компилятор также создает конкретную функцию из шаблона. Однако это выражение не вызывает генерации вызова функции. Это хорошо описано в SFINAE Sono Buoni PDF.

Проверьте другие примеры С++ SFINAE.

Ответ 2

Это всего лишь комбинация двух известных трюков. SFINAE говорит, что "смена замены - это не ошибка" - это именно то, что вы сделали. Использование sizeof, чтобы компилятор мог заменить аргументы шаблона в выражении без его выполнения, также является общим.

Извините: -)