【问题标题】:Define friend template method outside namespace在命名空间外定义友元模板方法
【发布时间】:2013-04-19 08:20:44
【问题描述】:

我的代码具有以下基本结构:

namespace A{

    template<class T,unsigned DIM>
    class CMyTable{
        ...
            public:
            template<class T,unsigned DIM>
            friend std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec);
        }    

    };

}

最初的问题是让我的操作员

我试过这个解决方案:How do I define friends in global namespace within another C++ namespace?

namespace A{

    template<class T,unsigned DIM>
    class CMyTable;
}

template<class T,unsigned DIM>
std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec);

namespace A{

    template<class T,unsigned DIM>
    class CMyTable{
        ...
            public:
            template<class T,unsigned DIM>
            friend std::ostream& ::operator<<(std::ostream& s, const CMyTable<T,DIM>& vec);
        }    

    };

}

template<class T,unsigned DIM>
std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec){
// [...]
}

我收到此错误:错误 C2063: 'operator

public:
template<class T,unsigned DIM>
friend std::ostream& ::operator<<(std::ostream& s, const CMyTable<T,DIM>& 

有人有什么想法吗?

谢谢。

【问题讨论】:

    标签: c++ templates namespaces operators friend


    【解决方案1】:

    如果您的 ostream 重载必须是 friend需要访问受保护的成员),则将其定义为内联,以便您可以使用传递给类的模板参数。

    namespace A{
    
        template<class T,unsigned DIM>
        class CMyTable{
            ...
            public:
            // template<class T,unsigned DIM>  // This will shadow otherwise
            friend std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec) {
            // [...]
            }
        };
    }
    

    否则,从类和命名空间中完全删除其声明,并将其定义为外部模板重载。

    请记住,如果它不需要访问私有或受保护元素,则不必成为朋友。

    namespace A{
       template<class T,unsigned DIM>
       class CMyTable{
        ...
            public:
        };
    }
    
    
    
    template<class T,unsigned DIM>
    std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec){
    // [...]
    }
    

    第三个选项是让它保持朋友关系,但在命名空间 A 中定义它

    namespace A{
    
        template<class T,unsigned DIM>
        class CMyTable{
            public:
                int i;
    
            template<class V,unsigned E>
            friend std::ostream& operator<<(std::ostream& s, const CMyTable<V,E>& vec);
        };  
    
    };
    //
    //
    
    namespace A{
    
        template<class T,unsigned DIM>
        std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec) {
            s << vec.i;
        }
    
    }
    

    【讨论】:

    • 感谢您的回答。但我需要我的方法来成为朋友。我只是不想在我的类中定义访问器(甚至是 const)。
    • @Haimo 那么内联(在类内)定义它有什么问题?
    • 我要访问全局命名空间中的算子。
    • @Haimo 好的,如果您出于某种原因不想内联定义它,那么您必须在命名空间 A 中定义它。请参阅编辑。第三个选项。
    【解决方案2】:

    输出操作符实际上是类的接口,所以逻辑上应该在命名空间中,类声明的地方,但是为了让你的代码工作,你可以使用

    namespace A{
    
        template<class T,unsigned DIM>
        class CMyTable;
    }
    
    // friend is not correct here.
    template<class T,unsigned DIM>
    /*friend*/ std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec);
    
    namespace A{
    
        template<class T,unsigned DIM>
        class CMyTable{
            ...
                public:
                // choose another names of template pars.
                // or use
                //friend std::ostream& (::operator << <>)(std::ostream& s,
                //const CMyTable<T, DIM>&);
                /*template<class T,unsigned DIM>*/
                template<class U, unsigned D>
                friend std::ostream& (::operator <<)(std::ostream&,
                const CMyTable<U,D>&);
            };
    }
    
    template<class T,unsigned DIM>
    std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec){
    // [...]
    }
    

    【讨论】:

    • 给朋友,发错了。我编辑了帖子。我更改了模板参数的名称,但仍然出现相同的错误:'operator
    • @Haimo 好好看看代码...注:friend std::ostream&amp; **(**::operator &lt;&lt;**)**
    • 抱歉,我实际上是复制/粘贴了您的代码。所以我也添加了括号。但是还是不行……
    • @Haimo,我不知道,为什么会出现此错误。看看例子 - 它和你看到的一样好用。
    • 这可能是我的编译器(我正在使用 VS2005)让我参与其中吗?
    猜你喜欢
    • 2018-10-20
    • 2020-03-30
    • 1970-01-01
    • 2018-06-24
    • 2013-05-19
    • 1970-01-01
    • 2018-04-12
    • 2020-09-19
    • 1970-01-01
    相关资源
    最近更新 更多