程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了是否可以为模板类型定义 operator<<?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决是否可以为模板类型定义 operator<<??

开发过程中遇到是否可以为模板类型定义 operator<<?的问题如何解决?下面主要结合日常开发的经验,给出你关于是否可以为模板类型定义 operator<<?的解决方法建议,希望对你解决是否可以为模板类型定义 operator<<?有所启发或帮助;

我想打印 STL 类型的值,例如 std::maps,例如:

int main()
{
    std::map<int,std::vector<int>> t = {{1,{2,3}},{4,{5}}};
    std::cout << t << std::endl;
    return 0;
}

这失败了,因为没有为这些类型定义 operator<<

如果我尝试自己定义它,我还必须转发声明我的定义,否则编译失败:

error: call to function 'operator<<' that is neither visible in the template deFinition nor found by argument-dependent lookup
        o << sep << "{" << x.first << "," << x.second << "}";
...
note: 'operator<<' should be declared prior to the call site std::ostream& operator<< (std::ostream& o,const std::vector<T>& veC)

这很不幸,因为必须前向声明方法需要为每种类型使用两个包含(先前向声明,然后是实现)。

  • 有没有办法以模块化的方式为模板类型定义 operator<<
  • 这种困难是否是 operator<< 不适用于开箱即用的 STL 类型的原因?

:A working implementation with forWARD declarations

解决方法

在您的要点中,operator<<std::map<K,V> 重载是在 std::vector<T> 的重载之前定义的。

GCC 很乐意接受您的代码而不会引发任何错误,而 Clang(我猜是您正在使用的那个)完全拒绝使用您发布的消息编译它,这基本上是说没有好的 operator<<尚未定义 std::vector<T>

我应该仔细检查标准在这种情况下指定的内容,但我的第一印象是 GCC 正在接受您的代码,因为 operator<<(ostream&,const std::vector<T>&) 是在实例化时定义的(发生在 @H_779_3@main(),当您调用std::cout << t),而 Clang 严格认为只有在定义模板时已知的那些函数才是可见的。

如果您为 operator<<(ostream&,const std::vector<T>&) 添加前向声明,它在 operator<<(ostream&,const std::map<K,V>) 中变得明确可见,并且 Clang 会编译您的代码。

只是交换函数也足以让您的特定代码在 Clang 下构建,但如果您尝试这样做,它会再次中断

int main()
{
    std::vector<std::map<int,int>> u = {{{1,2},{3,4}},{{4,5}}};

    std::cout << u << std::endl;

    return 0;
}

因为现在 Clang 不会在 std::map<K,V> 的实现中看到正确的 std::vector<T> 重载(尽管使用 GCC,它仍然可以正常构建)

大佬总结

以上是大佬教程为你收集整理的是否可以为模板类型定义 operator<<?全部内容,希望文章能够帮你解决是否可以为模板类型定义 operator<<?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。