C++ 模板结构中的友元运算符引发重新定义错误
考虑以下代码:C++ 模板结构中的友元运算符引发重新定义错误,c++,templates,c++11,operator-overloading,C++,Templates,C++11,Operator Overloading,考虑以下代码: template<typename T,typename K> struct A{ friend std::ostream& operator<<(std::ostream& out, K x) { // Do some output return out; } }; int main(){ A<int,int> i; A<double,int> j; }
template<typename T,typename K>
struct A{
friend std::ostream& operator<<(std::ostream& out, K x) {
// Do some output
return out;
}
};
int main(){
A<int,int> i;
A<double,int> j;
}
模板
结构A{
friend std::ostream&operator将方法分解为基类:
template <typename K>
struct ABase
{
friend std::ostream& operator<<(std::ostream& out, K x) {
// Do some output
return out;
}
};
template <typename T,typename K>
struct A : public ABase<K>
{};
模板
结构基
{
friend std::ostream&operator我真的不认为这样声明一个朋友有什么用,不过你可以这样做:
template<typename T, typename K>
struct A{
template<typename L>
friend std::ostream& operator<<(std::ostream& out, L const &x);
};
template<typename T>
std::ostream& operator<<(std::ostream& out, T const &x) {
// ...
return out;
}
模板
结构A{
模板
friend std::ostream&operator您的问题有以下错误
假设它是一个存根,并且您的类有一些私有的东西,因此它需要声明一个友元,这样做的目的是友元位于类本身的外部,但可以访问其中的私有内容
在您的例子中,您将一个参数的流函数声明为友元。这很好。这意味着如果有人创建一个类Bar
,并希望定义如何流化Bar
,那么他们的实现可以访问a
中任何类型T
的任何内容
模板与运算符的冲突如果要流式处理对象,则应使用正确的签名
template<typename T,typename K>
struct A{
friend std::ostream& operator<<(std::ostream& out, const A& x) {
// Do some output
return out;
}
};
模板
结构A{
friend std::ostream&Operator在定义Operator时是否需要T
,Operator是否已经可以使用Operator?我不太明白为什么要实现Operator。你在类中定义与类相关的操作,而不是它的模板参数。我同意CashCow的观点。在你的示例中,流插入器确实不需要是struct a
的朋友。它可能需要是K
的朋友,但它不需要知道a
的任何内部内容。你的回答也没有实际意义。不知道为什么它得到了7upvotes@CashCow嗯,这没有多大意义,但回答了问题/解决了公关问题问题:friend操作符是类(模板实例)中的模板。因此,允许使用多个定义。此处的friend运算符根本不定义与类相关的任何内容。cout@CashCow是如何定义的?真正的问题是,为什么会有人希望这样做。您是否看到此设计中的任何实际用途?我根本看不到用户试图实现什么。假设A有一些私人成员(如果不是,你不需要交任何朋友)您可以声明友谊以授予对参数类型的流函数或所有流函数的访问权限。尽管尝试实现流是完全错误的,并且超出了类的范围。您的声明有效吗?可能标准已更改,要使其生效,您必须先前向声明模板并使用朋友声明中的模板在名称范围中,我记得过去我需要做:朋友模板std::ostream&operator
template<typename T>
std::ostream& operator<<(std::ostream& out, T const &x);
template<typename T, typename K>
struct A{
friend std::ostream& operator<<<K>(std::ostream& out, K const &x);
};
template<typename T>
std::ostream& operator<<(std::ostream& out, T const &x) {
// ...
return out;
}
template< typename X, typename Y >
struct A
{
friend void a_print( std::ostream& Y const & ); // foo external function with Y as parameter, can access this
};
std::ostream & operator<<( std::ostream & out, Bar const& bar )
{
a_print( out, bar );
return out;
}
void a_print( Bar const& bar, std::ostream & out )
{
// implement and call private members of A<Foo, Bar>
return out;
}
template<typename T,typename K>
struct A{
friend std::ostream& operator<<(std::ostream& out, const A& x) {
// Do some output
return out;
}
};