模板 类 的用户定义运算符的 C++ 隐式转换
c++ implicit conversion on user-defined operator for template classes
我有一个结构模板 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;
}
我创建了一个结构模板 B<x>
,它可以转换为 A<x>
。
template<int x>
struct B{
int b=3;
operator A<x>(){
return {b+10};
}
};
现在我希望在调用B<x> + int
时将B<x>
转换为A<x>
。
int main(){
std::cout<<(A<12>{9}+10)<<std::endl;//OK
std::cout<<(B<12>{9}+10)<<std::endl;//Error
return 0;
}
我读了Implicit conversion when overloading operators for template classes写了
template<int x>
struct B{
int b=3;
operator A<x>(){
return {b+10};
}
friend int operator+(A<x> a, int b);
};
,但它不起作用,因为声明的 friend int operator+(A<x> a, int b)
与 template<int x> int operator+(A<x> a, int b)
.
不匹配
看了做了朋友声明模板,但是没有成功,因为模板参数无法推导
当然我可以为 A 和 B 都写 operator+,但我有几十个运算符,我不想这样做。
正确的做法是什么?
希望对你有所帮助
我有模板朋友operator+
派生自 A<x>
并编译,但在调用 friend operator+
变量后 a
是 uninit 所以我得到了立即值。您必须以某种方式设置 a
,这似乎有效。
#include <iostream>
template<int x>
struct A
{
int a{x};
};
template<int x>
int operator+(A<x> a, int b)
{
return a.a+b;
}
template<int x>
struct B : A<x>
{
int b;
template<int U>
friend int operator+(A<U> a, int b);
};
int main(void)
{
std::cout<< (A<20>{}+10)<<std::endl; // prints 30
std::cout<< (B<10>{}+10)<<std::endl; // prints 20
return 0;
}
你可能已经看过了,但至少它仍然可以进行显式转换,而且它可能会有用:
int main(){
std::cout<<(A<12>{9}+10)<<std::endl; // prints 19
std::cout<<(static_cast<A<12>>(B<12>{9})+10)<<std::endl; // prints 29
return 0;
}
查看为 A
创建非成员 operator+
的两种方法,我们可以将其设为函数模板:
template <int x>
int operator+(A<x>, int);
这与 B<x>
不匹配,因为我们只是在进行模板推导,不允许转换。
或者,我们可以将其设为非模板友元:
template <int x>
struct A {
friend int operator+(A a, int );
};
也不会匹配 B<x>
因为名称查找不会考虑该函数。除非,也就是说,我们告诉它:
template <int x>
struct B {
friend int operator+(A<x>, int ); // NB: not a template
};
现在,会考虑我们原来的非模板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;
}
打印
19
29
我有一个结构模板 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;
}
我创建了一个结构模板 B<x>
,它可以转换为 A<x>
。
template<int x>
struct B{
int b=3;
operator A<x>(){
return {b+10};
}
};
现在我希望在调用B<x> + int
时将B<x>
转换为A<x>
。
int main(){
std::cout<<(A<12>{9}+10)<<std::endl;//OK
std::cout<<(B<12>{9}+10)<<std::endl;//Error
return 0;
}
我读了Implicit conversion when overloading operators for template classes写了
template<int x>
struct B{
int b=3;
operator A<x>(){
return {b+10};
}
friend int operator+(A<x> a, int b);
};
,但它不起作用,因为声明的 friend int operator+(A<x> a, int b)
与 template<int x> int operator+(A<x> a, int b)
.
看了
当然我可以为 A 和 B 都写 operator+,但我有几十个运算符,我不想这样做。
正确的做法是什么?
希望对你有所帮助
我有模板朋友operator+
派生自 A<x>
并编译,但在调用 friend operator+
变量后 a
是 uninit 所以我得到了立即值。您必须以某种方式设置 a
,这似乎有效。
#include <iostream>
template<int x>
struct A
{
int a{x};
};
template<int x>
int operator+(A<x> a, int b)
{
return a.a+b;
}
template<int x>
struct B : A<x>
{
int b;
template<int U>
friend int operator+(A<U> a, int b);
};
int main(void)
{
std::cout<< (A<20>{}+10)<<std::endl; // prints 30
std::cout<< (B<10>{}+10)<<std::endl; // prints 20
return 0;
}
你可能已经看过了,但至少它仍然可以进行显式转换,而且它可能会有用:
int main(){
std::cout<<(A<12>{9}+10)<<std::endl; // prints 19
std::cout<<(static_cast<A<12>>(B<12>{9})+10)<<std::endl; // prints 29
return 0;
}
查看为 A
创建非成员 operator+
的两种方法,我们可以将其设为函数模板:
template <int x>
int operator+(A<x>, int);
这与 B<x>
不匹配,因为我们只是在进行模板推导,不允许转换。
或者,我们可以将其设为非模板友元:
template <int x>
struct A {
friend int operator+(A a, int );
};
也不会匹配 B<x>
因为名称查找不会考虑该函数。除非,也就是说,我们告诉它:
template <int x>
struct B {
friend int operator+(A<x>, int ); // NB: not a template
};
现在,会考虑我们原来的非模板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;
}
打印
19
29