我有类:
class IntegerVector:
{
IntegerVector operator * (const int scalar) const;
};
class RealVector:
{
RealVector(const IntegerVector &other);
RealVector operator * (const double scalar) const;
};
如何强制表达式:integer_vector*1.5
等效于RealVector(integer_vector)*1.5
,而不是现在的integer_vector*int(1.5)
?
编辑
顺便说一句,有很多这样的运算符,所以定义RealVector IntegerVector::operator * (const double scalar) const
不是很令人满意。
在C++11中,您可以利用内置的类型提升,如
#include <type_traits>
class IntegerVector;
class RealVector;
template <class T> struct VectorForType {};
template <> struct VectorForType<int> {typedef IntegerVector type;};
template <> struct VectorForType<double> {typedef RealVector type;};
// This is where we figure out what C++ would do..
template <class X, class Y> struct VectorForTypes
{
typedef typename VectorForType<decltype(X()*Y())>::type type;
};
class IntegerVector
{
public:
template <class T> struct ResultVector
{
typedef typename VectorForTypes<int, T>::type type;
};
template <class T>
typename ResultVector<T>::type operator*(const T scalar) const;
};
class RealVector
{
public:
template <class T> struct ResultVector
{
typedef typename VectorForTypes<double, T>::type type;
};
RealVector();
RealVector(const IntegerVector &other);
template <class T>
typename ResultVector<T>::type operator*(const T scalar) const;
};
int main()
{
IntegerVector v;
auto Result=v*1.5;
static_assert(std::is_same<decltype(Result), RealVector>::value, "Oh no!");
}
如果您需要在没有decltype的情况下这样做,您可能也可以将类型提升结果实现为元函数。我想运营商的实现看起来像这样:
template <class T> inline
typename ResultVector<T>::type IntegerVector::operator*(const T scalar) const
{
typename ResultVector<T>::type Result(this->GetLength());
for (std::size_t i=0; i<this->GetLength(); ++i)
Result[i]=(*this)*scalar;
return Result;
}
您可以使用这样的东西。。。这是一个解决方案,但很奇怪,但我无法发明更好的东西。
#include <iostream>
#include <type_traits>
class IntegerVector;
class RealVector
{
public:
RealVector(const IntegerVector &other) { }
RealVector operator * (const double scalar) const { std::cout << "RealV called" << std::endl; return *this; }
};
class IntegerVector
{
public:
IntegerVector operator * (const int scalar) const
{
std::cout << "IntV called" << std::endl;
return *this;
}
template<typename T>
typename std::conditional<std::is_same<T, int>::value, IntegerVector, RealVector>::type
operator * (const T scalar) const
{
decltype(operator *<T>(scalar)) object(*this);
return object * scalar;
}
};
int main()
{
IntegerVector v;
v * 1.5;
}
http://liveworkspace.org/code/b72cde05ca287042300f4aff0f185a42