0

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

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);
        }    

    };

}

最初的问题是让我的 operator<< 在命名空间 A 之外。

我尝试了这个解决方案:如何在另一个 C++ 命名空间内的全局命名空间中定义朋友?

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 <<' : not a function inside the class declaration。

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

有没有人有任何想法?

谢谢。

4

2 回答 2

0

输出运算符实际上是类的接口,因此,从逻辑上讲,它应该在声明类的命名空间中,但是为了使您的代码正常工作,您可以使用

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){
// [...]
}
于 2013-04-19T08:25:04.667 回答
0

如果您的 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;
    }

}
于 2013-04-19T08:35:03.363 回答