C ++自定义控制台类 - 如何处理“<
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++自定义控制台类 - 如何处理“<相关的知识,希望对你有一定的参考价值。
我在Windows中用C ++编写自定义控制台,希望打印出任何对象或至少处理每个对象。
这是我的WriteLine方法
template<typename T>
inline void WriteLine(const T& t)
{
std::cout << t << "
";
}
我有一个基础“对象”类,它有一个重载的<<运算符,如图所示
friend std::ostream& operator<<(std::ostream& stream, const object& object)
{
stream << object.toString();
return stream;
}
我的所有课程都应该来自于此。但是,他们是一种检查类是否有一个重载<<运算符的方法,如果不处理它,这就是我的意思。 (伪代码)
template<typename T>
inline void WriteLine(const T& t)
{
//check if the object has an overloaded << operator
if(itdoes){
//then print as normal
std::cout << t;
}
else {
//if it hasn't been overloaded, just print the type of the object using <typeinfo>
std::cout << typeid(T).name()
}
}
简而言之,我希望代码在类型(T)没有被重载时编译和处理这种情况,而不是抛出编译错误。如果它没有被重载,只需打印出对象类型名称谢谢
答案
您应该能够使用SFINAE和tag dispatch执行此操作:
template <class T, class = void>
struct HasInserter :
std::false_type
{};
template <class T>
struct HasInserter<T, std::void_t<decltype(std::declval<std::ostream&>() << std::declval<const T>())>> :
std::true_type
{};
template <class T>
void WriteLine(const T &t, std::true_type)
{
std::cout << t << '
';
}
template <class T>
void WriteLine(const T &t, std::false_type)
{
std::cout << typeid(T).name() << '
';
};
template <class T>
void WriteLine(const T &t)
{
WriteLine(t, HasInserter<T>{});
}
这创建了一个辅助特征,它使用SFINAE来区分表达式stream << t
是否格式正确。然后WriteLine
函数使用该特征进行标签调度。
请注意,std::void_t
是C ++ 17的一个特性,但在标准的早期版本中实现它是微不足道的,因此上述解决方案可以在C ++ 11中使用。
正如@mdatsev在评论中指出的那样,如果你正在使用Boost,你不必自己实现这个特性,你可以使用boost::has_left_shift<std::ostream&, const T>
代替(用boost::true_type
代替std::true_type
,同样用false)。
以上是关于C ++自定义控制台类 - 如何处理“<的主要内容,如果未能解决你的问题,请参考以下文章