首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何说明如何调用操作程序<<的模板重载?

如何说明如何调用操作程序<<的模板重载?
EN

Stack Overflow用户
提问于 2019-11-08 00:54:04
回答 3查看 101关注 0票数 2

考虑以下示例代码,用于重载operator<<class A

代码语言:javascript
复制
#include <iostream>
class A {
    template <typename T>
    friend A &operator<<(A &a, const T &t)
    {
         std::cout << t << std::endl;
         return a;
    }
    friend A &operator<<(A &a, const std::string &t)
    {
         return operator<<<std::string>(a, t + "x");
    }
};

我的意图是第二个操作符显式调用第一个操作符。

但是,在g++ 7.4中,这在

在函数'A& operator<<(A&,const string&)‘中: 无法定义的“operator<<” (a,t+ "x"); 财政、财政、金融、金融、商业、金融等领域的自愿性、商品性、自愿性、 token =‘token 10’>标记前的预期主表达式 (a,t+ "x"); /T1559.2-1995

但是,我不明白为什么这不应该编译。

这是“哥德波特”的密码。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-11-08 01:35:25

调用一个函数而不是调用一个操作符。

代码语言:javascript
复制
#include <iostream>
class A {
    template <typename T>
    static A &print(A &a, const T &t)
    {
        std::cout << t << std::endl;
        return a;
    }

    template <typename T>
    friend A &operator<<(A &a, const T &t)
    {
         return print(a, t);
    }
    friend A &operator<<(A &a, const std::string &t)
    {
         return print(a, t + "x");
    }
};
票数 1
EN

Stack Overflow用户

发布于 2019-11-08 01:36:04

类中的朋友函数不暴露于任何作用域.朋友注入曾经是一种东西(在ADL发明之前),但是现在除了ADL之外,没有其他方法来调用它们,除非您事先声明它们。在这种情况下,解决办法是事先声明类之外的模板函数。

代码语言:javascript
复制
class A;

template <typename T>
A &operator<<(A &a, const T &t);
票数 2
EN

Stack Overflow用户

发布于 2019-11-08 02:47:11

您似乎希望专门化模板函数,但您做得不太对。它应该更像这样:

代码语言:javascript
复制
template <> friend A& operator<< <std::string>(A &a, const std::string &t)
{
    // Print in here some how. It's not exactly clear to me how you intend to
    // do this, as doing something like a << t will create infinite recursion

    // finally, return a
    return a;
}

另一个选项是切换函数的顺序,在创建第一个函数之后创建模板函数:

代码语言:javascript
复制
friend A &operator<<(A &a, const std::string &t)
{
    // Again, still not sure what you want to do here
    // I just want to stress again though, don't do something
    // like a << t, or operator<<(a,t)
    // That will crash hard and fast, as there is no way to resolve
    // it. It will create infinite recursion

    return a;
}

template <typename T>
friend A &operator<<(A &a, const T &t)
{
     std::cout << t << std::endl;
     return a;
}

我的意图是第二个操作符显式调用第一个操作符。

因此,首先,在这种情况下,您需要实际需要第一个选项。

其次,要做到这一点,您需要为t选择一个类型。你会这样做的:

代码语言:javascript
复制
operator<< <SomeType>(a,t);

请记住,t需要成为隐式转换 to SomeType。否则,需要通过调用构造函数来创建SomeType

代码语言:javascript
复制
operator<< <SomeType>(a,SomeType(/* parameters to construct a SomeType ... */));

注意:做类似operator<< <SomeType>(a,t + "x")的事情总是会变成无限递归,最终会崩溃。这是因为t + "x"总是一个std::string。这意味着编译器总是无限地调用这个函数的重载,直到它最终从堆栈溢出崩溃。所以别那么做。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58758932

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档