【问题标题】:Declare non-template friend function for template class outside the class为类外的模板类声明非模板友元函数
【发布时间】:2016-03-15 20:51:33
【问题描述】:

以下非模板代码works well

struct A { };

struct B
{
    B() {}
    B(const A&) {}
    friend B operator+(const B&) { return B(); }    
};

B operator+(const B&);

int main()
{
    A a;
    B b;
    +b;
    +a;
}

但如果我在这段代码中创建类模板:

template <class T>
struct A { };

template <class T>
struct B
{
    B() {}
    B(const A<T>&) {}
    friend B operator+(const B&) { return B(); }    
};

template <class T>
B<T> operator+(const B<T>&); // not really what I want 

int main()
{
    A<int> a;
    B<int> b;
    +b;
    +a;
}

某种troubles appear

错误:'operator+' 不匹配(操作数类型为'A')

是否可以在类外为模板类声明非模板友元函数(就像我在上面为非模板类​​所做的那样)

我可以通过为A&lt;T&gt; 参数添加template operator 并在里面调用朋友函数来解决问题,但这并不有趣。

UPD:

另一个解决方法(受R Sahu's answer 启发)是为A 类添加friend 声明:

template <class T>
struct A { 
    friend B<T> operator+(const B<T>&);
};

但是这个gives a warning,我不知道如何正确修复它。

【问题讨论】:

  • 我不确定你想要什么。 B这里是一个模板,所以需要一个模板参数来对其进行操作。如果不是动态确定的模板参数应该是什么?
  • @IceFire dynamically 是什么意思?

标签: c++ templates friend-function


【解决方案1】:

是否可以在类外为模板类声明非模板友元函数(就像我在上面为非模板类​​所做的那样)?

是的,这是可能的。但是,您可能还需要一个函数模板,并确保 operator+&lt;int&gt;A&lt;int&gt;friendoperator+&lt;double&gt;friendA&lt;double&gt; 等。

请参阅https://stackoverflow.com/a/35854179/434551 了解如何做到这一点。

【讨论】:

  • A 类添加friend 声明有效。但是warning appears.
  • @alexolut,警告信息是有道理的。函数B&lt;T&gt; operator+(const B&lt;T&gt;&amp;); 在被制作为friendA&lt;T&gt; 之前尚未被声明为函数模板。看一个不使用A的简化版:ideone.com/U5EJPp。另一个有A 但有A 的版本并没有做太多:ideone.com/WjpxyY
  • 第二个版本不使用a 对象。如果我添加它 - 我得到了same error,就像原来的问题一样。注:如果没有发生错误,ideone 不会显示任何警告。
  • @alexolut,我取出了 +a 的行,因为它是一个未定义的函数。 B&lt;T&gt; operator+(const B&lt;T&gt;&amp;); 仅支持B&lt;T&gt; 上的一元+ 运算符,而不支持A&lt;T&gt;
  • 但是 B 的 ctor 从 A 到 B 的隐式转换,我的愿望是让它工作(例如 A & B 的非模板版本)
【解决方案2】:

是否可以在类外为模板类声明非模板友元函数?

回答:是的,但是...您需要为您使用的每个组合声明一个函数:

这个函数解决了你的 puntual 声明的问题:

A<int> operator+(const A<int>&) { return A<int>(); }

但是,如果使用 A,则需要显式声明其他函数:

A<double> operator+(const A<double>&) { return A<double>(); }

不是必需的朋友,因为在结构中所有成员都是公共的

【讨论】:

  • 我的问题只是关于声明,而不是定义。 operator+ 的唯一一个定义位于类的 B 定义中,我不想添加任何其他重载函数。 friend 对于隐式参数转换是必需的,而不是访问私有成员。见here & here
猜你喜欢
  • 2013-09-18
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
  • 2018-02-22
  • 2022-07-08
  • 1970-01-01
相关资源
最近更新 更多