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
.
Ответы
Ответ 1
Это хорошо известная техника, я боюсь: -)
Использование вызова функции в операторе sizeof
дает указание компилятору, конечно же, выполнять дедукцию аргументов и соответствие функций во время компиляции. Кроме того, с помощью функции шаблона компилятор также создает конкретную функцию из шаблона. Однако это выражение не вызывает генерации вызова функции. Это хорошо описано в SFINAE Sono Buoni PDF.
Проверьте другие примеры С++ SFINAE.
Ответ 2
Это всего лишь комбинация двух известных трюков. SFINAE говорит, что "смена замены - это не ошибка" - это именно то, что вы сделали. Использование sizeof
, чтобы компилятор мог заменить аргументы шаблона в выражении без его выполнения, также является общим.
Извините: -)