我刚刚了解了如何检查是否为类型提供了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
。
答案 0 :(得分:6)
这是一项众所周知的技术,我担心: - )
在sizeof
运算符中使用函数调用指示编译器在编译时执行参数推导和函数匹配。此外,使用模板函数,编译器还可以从模板中实例化具体函数。但是,此表达式不会导致生成函数调用。它在SFINAE Sono Buoni PDF中有详细描述。
检查其他C++ SFINAE examples。
答案 1 :(得分:1)
这只是两个众所周知的技巧的结合。 SFINAE说'替换失败不是错误' - 这正是你所做的。使用sizeof
让编译器将模板参数替换为表达式而不实际执行它也很常见。
抱歉: - )