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 ++自定义控制台类 - 如何处理“<的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 Android 中远程视图的异常(自定义小部件或自定义通知)?

如何处理交叉导入?

scrapy中如何处理大文件下载?

JVM 如何处理 RuntimeException(s)

spring mvc 异常如何处理

如何处理自定义 UIViewController 委托 (ARC)?