Я просто узнал, как проверить если 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;
};
Действительно ли этот прием известен, или я только что выиграл метапрограммирование Нобелевская премия?;)
Править: Я сделал код более простым понять и легче адаптироваться с двумя глобальными объявлениями шаблона функции lvalue_of_type
и rvalue_of_type
.
Это хорошо известная техника, я боюсь: -)
Использование функционального вызова в операторе Sizeof
Указывает компилятору выполнить вычет аргумента и Соответствие функции, конечно, при компиляции времени. Также с функцией шаблона компилятор также создает конкретную функцию из шаблона. Однако это выражение не вызывает создания функционального вызова. Он хорошо описан в Sfinae Sono Buoni PDF.
Проверьте другие примеры SFINAE C ++ .
Это всего лишь комбинация двух известных трюков. SFINAE говорит, что "сбой при замене не является ошибкой" - это именно то, что вы сделали. Использование sizeof
для того, чтобы компилятор подставлял аргументы шаблонов в выражение, не выполняя его на самом деле, также распространено.
Извините :-)
.