重载运算符<<对于模板结构中定义的成员结构

时间:2014-05-28 08:05:06

标签: c++ templates operator-overloading

你好亲爱的StackOverflowers!

我遇到了一个包含另一个(但非模板)结构的模板结构的问题。

这就是事情:

  1. 结构B是非模板,在模板结构A中定义。

  2. Strcure B受到保护"因为它只存在于结构A和没有人的目的,所以没有别的东西在结构A之外使用它。

  3. 运营商的重载<<对于结构B,可以将类型B的对象发送到标准输出" cout<< B_type_object;" (以及它的A朋友,以便它可以访问受保护的B)。

  4. 上述B对象的打印只能通过A中定义的方法完成(因为" 2。")。

  5. 只要两个结构都是非模板,一切都像魅力一样。

  6. A是模板的时刻我收到错误消息(在代码部分提供)。

  7. 这是工作代码(其中A不是模板):

    #include <iostream>
    #include <string>
    
    struct A
    {
    
    protected:
        struct B
        {
            std::string something;
    
            B& operator= (const std::string&& rhs)
            {
                this->something = std::move(rhs);
                return *this;
            }
        };
    
        B B_object;
    
        friend std::ostream& operator<< (std::ostream& output, const typename A::B& ob);
    
    public:
        void method ()
        {
            B_object = "This is text.";
            //No error here
            std::cout << B_object;
        }
    };
    
    
    
    std::ostream& operator<< (std::ostream& output, const typename A::B& ob)
    {
        output << ob.something;
        return output;
    }
    
    
    
    int main(int argc, const char * argv[])
    {
        A obj;
        obj.method();
    
        return 0;
    }
    

    这是不起作用的代码

    #include <iostream>
    #include <string>
    
    template <typename T>
    struct A
    {
        T variable;
    
    protected:
        struct B
        {
            std::string something;
    
            B& operator= (const std::string&& rhs)
            {
                this->something = std::move(rhs);
                return *this;
            }
        };
    
        B B_object;
    
        template <typename X> friend std::ostream& operator<< (std::ostream& output, typename A/*<X>*/::B& ob);
    
    public:
        void method ()
        {
            B_object = "This is text.";
    
            //ERROR: Invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'A<int>::B')
            std::cout << B_object;
        }
    };
    
    
    
    template <typename X>
    std::ostream& operator<< (std::ostream& output, typename A<X>::B& ob)
    {
        output << ob.something;
        return output;
    }
    
    
    
    int main(int argc, const char * argv[])
    {
        A<int> obj;
        obj.method();
    
        return 0;
    }
    

1 个答案:

答案 0 :(得分:2)

只需在B中内联运算符,然后就可以了:

...
struct B
{
    std::string something;

    B& operator= (const std::string&& rhs)
    {
        this->something = std::move(rhs);
        return *this;
    }

    friend std::ostream& operator<< (std::ostream& output, const typename A<T>::B& ob)
    {
        output << ob.something;
        return output;
    }
};
...

这样做的另一个好处是,您不会friend任何operator<< A<X> A<string>::B。在您的示例中,接受A<int>::B的运营商也将是{{1}}的朋友。有关更深入的解释,请参阅以下答案: https://stackoverflow.com/a/4661372/36565