template <class T>
class A
{
private:
T m_var;
public:
operator T () const { return m_var; }
........
}
template<class T, class U, class V>
const A<T> operator+ (const U& r_var1, const V& r_var2)
{ return A<T> ( (T)r_var1 + (T)r_var2 ); }
这个想法是为这些情况重载+运算符一次(而不是三次): number + A,A + number,A + A(其中number是T型,与m_var相同)。 一个有趣的例子是如果m_var是例如int和r_var很长。
任何帮助都将受到高度赞赏。谢谢。
答案 0 :(得分:6)
实现所需要的常见模式是在相反的方向上实际执行它:提供从T
到模板的隐式转换,并仅定义模板的运算符。
template <typename T>
struct test {
T m_var;
test( T const & t ) : m_var(t) {} // implicit conversion
test& operator+=( T const & rhs ) {
m_var += rhs.m_var;
}
friend test operator+( test lhs, test const & rhs ) { // *
return lhs += rhs;
}
};
// * friend only to allow us to define it inside the class declaration
关于成语的几个细节:operator+
被声明为朋友,只允许我们在类花括号内定义一个自由函数。在查找编译器时,这有一些优点,因为如果其中一个参数已经是test
,它只会考虑该运算符。
由于构造函数是隐式的,因此调用test<int> a(0); test<int> b = a + 5;
将转换为等效的test<int> b( a + test<int>(5) );
相反,如果切换到5 + a
。
operator+
以operator+=
表示,通过按值获取第一个参数,在单行中实现。如果运营商更复杂,那么这将为两个运营商提供单一的实施。
答案 1 :(得分:2)
运算符+的问题是你有3个模板参数,一个用于返回类型和强制转换,但编译器无法自动解析该参数。
你也会在演员阵容中犯下一些罪恶。
如果在命名空间中将operator +定义为自由模板函数,则可以利用它,它只对该命名空间中定义的类型有效。
在你的命名空间中,我将使用T和U
来定义template< typename T >
T operator+( const T & t1, const T& t2 )
{
T t( t1 );
t += t2; // defined within T in your namespace
return t;
}
template< typename T, typename U >
T operator+( const T& t, const U& u )
{
return t + T(u);
}
template< typename T, typename U >
T operator+( const U& u, const T& t )
{
return T(u) + t;
}
除非a和b中的一个类型位于定义模板的命名空间中,否则此模板不会覆盖a + b。
答案 2 :(得分:1)
你不应该重载op +用于你不了解的无关类型 - 这可能会破坏已经存在的完美工作代码。你应该将你的类作为op + overload的至少一个参数。
如果您不希望从T到A&lt; T&gt;的implicit conversion,那么我只会写出重载。如果您遵循“@ to @ =”重载模式,这是最清晰的代码,并且根本不长,
template<class T>
struct A {
explicit A(T);
A& operator+=(A const &other) {
m_var += other.m_var;
// This could be much longer, but however long it is doesn't change
// the length of the below overloads.
return *this;
}
A& operator+=(T const &other) {
*this += A(other);
return *this;
}
friend A operator+(A a, A const &b) {
a += b;
return a;
}
friend A operator+(A a, T const &b) {
a += A(b);
return a;
}
friend A operator+(T const &a, A b) {
b += A(a);
return b;
}
private:
T m_var;
};
答案 3 :(得分:0)
C ++ 0x解决方案
template <class T>
class A
{
private:
T m_var;
public:
operator T () const { return m_var; }
A(T x): m_var(x){}
};
template<class T,class U, class V>
auto operator+ (const U& r_var1, const V& r_var2) -> decltype(r_var1+r_var2)
{
return (r_var1 + r_var2 );
}
int main(){
A<int> a(5);
a = a+10;
a = 10 + a;
}
不幸的是,将template<class T,class U, class V>
更改为template<class U, class V>
会在gcc 4.5.1上调用segmentation fault。我不知道为什么?