c ++用于模板类的用户定义运算符的隐式转换

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 +,但我有几十个运算符,我不想这样做.

这样做的正确方法是什么?

Bar*_*rry 5

综观两种方式,使非成员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.


pin*_*gul 1

我尝试使用以下(可运行)代码编辑巴里的答案,该代码产生正确的输出,但它被拒绝了。

如果其他人好奇的话,我会在这里添加它。

#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)