【问题标题】:How to force a conversion to take precedence over other conversions?如何强制转换优先于其他转换?
【发布时间】:2012-07-14 09:01:50
【问题描述】:

我有课:

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 不是很令人满意。

【问题讨论】:

  • 嗯。 Mb 使用 RealVector(integer_vector) * 1.5?
  • 哈哈,当然,但是不,我的意思是隐式转换。 :-)
  • 只有在IntegerVector中有运算符RealVector()时才能进行隐式转换...
  • 换成IntegerVector算子如何*(RealVector real);其中实现可以控制实数到标量的转换
  • 我错了。没有显式的构造函数就足够了。

标签: c++ type-conversion operator-precedence


【解决方案1】:

在 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;
}

【讨论】:

  • 非常好!我不想切换到 C++11,所以我要找到一种方法来确定没有 decltype 的 X()*Y() 的结果类型。
【解决方案2】:

你可以使用这样的东西......这是解决方案,但很奇怪,但我无法发明更好的东西。

#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

【讨论】:

    猜你喜欢
    • 2012-04-13
    • 1970-01-01
    • 2019-05-15
    • 2021-06-25
    • 2021-05-28
    • 2019-01-10
    • 2020-07-02
    • 1970-01-01
    • 2012-09-02
    相关资源
    最近更新 更多