eiv*_*our 5 c++ templates operator-overloading friend-function c++14
我有一个结构模板A<x>和一个+运算符int.
#include <iostream>
template<int x>
struct A{
int a;
};
template<int x>
int operator+(A<x> a, int b){
return a.a+b;
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个B<x>可转换为的结构模板A<x>.
template<int x>
struct B{
int b=3;
operator A<x>(){
return {b+10};
}
};
Run Code Online (Sandbox Code Playgroud)
现在我希望在打电话时B<x>转换成.A<x>B<x> + int
int main(){
std::cout<<(A<12>{9}+10)<<std::endl;//OK
std::cout<<(B<12>{9}+10)<<std::endl;//Error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在重载模板类的运算符时读取了隐式转换并写了
template<int x>
struct B{
int b=3;
operator A<x>(){
return {b+10};
}
friend int operator+(A<x> a, int b);
};
Run Code Online (Sandbox Code Playgroud)
,但它不起作用,因为声明friend int operator+(A<x> a, int b)不匹配template<int x> int operator+(A<x> a, int b).
我读了C++ - 如何为类模板声明一个函数模板的朋友并制作好友声明模板,但它不起作用,因为无法推导出模板参数.
当然我可以为A和B编写operator +,但我有几十个运算符,我不想这样做.
这样做的正确方法是什么?
综观两种方式,使非成员operator+的A,我们既可以使一个函数模板:
template <int x>
int operator+(A<x>, int);
Run Code Online (Sandbox Code Playgroud)
这是不匹配的,B<x>因为我们只是做模板推导,不允许转换.
或者,我们可以使它成为非模板的朋友:
template <int x>
struct A {
friend int operator+(A a, int );
};
Run Code Online (Sandbox Code Playgroud)
也不会匹配,B<x>因为名称查找不会考虑该功能.除非,即我们告诉它:
template <int x>
struct B {
friend int operator+(A<x>, int ); // NB: not a template
};
Run Code Online (Sandbox Code Playgroud)
现在,我们operator+将考虑原始的非模板,转换将根据需要执行,您的代码打印29.
我尝试使用以下(可运行)代码编辑巴里的答案,该代码产生正确的输出,但它被拒绝了。
如果其他人好奇的话,我会在这里添加它。
#include <iostream>
template <int x>
struct A {
int a;
friend int operator+(A a, int b) { return a.a + b; }
};
template <int x>
struct B {
int b;
operator A<x>() { return {b+10}; }
friend int operator+(A<x>, int );
};
int main() {
std::cout << (A<12>{9} + 10) << std::endl;
std::cout << (B<12>{9} + 10) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
哪个打印
19
29
Run Code Online (Sandbox Code Playgroud)