Reputation: 95
In this minimal example I have a class A
with an operator +
defined outsise of it:
template<class T> class A {};
template<class T1, class T2> void operator+(A<T1> a, A<T2> b) {}
template<class T> class B : public A<T> {};
int main(int, char**) {
B<int> a, b;
a + b;
return 0;
}
I've tried to create an implicit conversion from B
to A
but it requires the operator+
to be a friend
of A
and be defined inside A
which will cause problems when more than one instance of A<...>
gets instantiated.
So, is there any other way to do this without having to define the operator+
again?
Thank you in advance for any help.
Upvotes: 0
Views: 55
Reputation: 275800
template<class T> class A {
template<class T2>
friend void operator+(A const& lhs, A<T2> const& rhs) {}
};
template<class T> class B : public A<T> {};
int main(int, char**) {
B<int> a, b;
a + b;
return 0;
}
this works. The assymetry in +
(one template, one not) ensure that multiple A
s don't conflict with their +
.
In some situations you really need lhs to be an instance of B
:
template<class T> struct A {
template<class D, class T2, std::enable_if_t<std::is_base_of<A, D>{}, bool> =true >
friend void operator+(D const& lhs, A<T2> const& rhs) {
std::cout << D::name() << "\n";
}
static std::string name() { return "A"; }
};
template<class T> struct B : public A<T> {
static std::string name() { return "B"; }
};
int main(int, char**) {
B<int> a, b;
a + b;
return 0;
}
which uses A
's operator+
, but the LHS is of type B
. Doing this for B<T2>
on the right hand side isn't very viable, it gets ridiculous.
Upvotes: 1