c ++ 在作为参数传递时强制隐式转换

佩恩

我在 C++ 中的隐式转换有问题。

我正在尝试为向量算术创建一些表达式模板(我知道已经存在相同的库。我只是在学习 C++,所以我想尝试一些模板)。

我想创建类 Vector,它能够像这样计算:

simd::test::Vector<char, 5> a;
simd::test::Vector<short, 5> b;

auto ret = a + b + a + b;

,输出将是短裤的向量,因为 short 的类型比 char 大。

现在,我有一个能够添加相同数据类型的向量的类。对于不同的类型,我必须调用显式转换:

//simd::test::Vector<short, 5>(a)
auto ret = simd::test::Vector<short, 5>(a) + b + simd::test::Vector<short, 5>(a) + b;

是否可以在传递到函数“operator+()”之前隐式转换 Vector?这是我的 Vector 代码:

#pragma once

#include <type_traits>

namespace simd {
  namespace test {

  template<typename R, std::size_t Dim,
      typename std::enable_if<std::is_arithmetic<R>::value>::type* = nullptr
  >
  class Vector_expression {
    public:
      static constexpr std::size_t size = Dim;

      virtual const R operator[] (std::size_t index) const = 0;

      virtual ~Vector_expression() = default;

  };

  template<typename T, std::size_t Dim>
  class Vector final : public Vector_expression<T, Dim> {
    private:
      T data[Dim];
    public:
      Vector() = default;

      template<typename R>
      Vector(const Vector_expression<R, Dim> &obj) {
        for(std::size_t index = 0; index < Dim; ++index) {
          data[index] = obj[index];
        }
      }

      template<typename R>
      Vector(Vector_expression<R, Dim> &&obj) {
        for(std::size_t index = 0; index < Dim; ++index) {
          data[index] = obj[index];
        }
      }

      template<typename R>
      Vector<T, Dim> & operator=(const Vector_expression<R, Dim> &obj) {
        for(std::size_t index = 0; index < Dim; ++index) {
          data[index] = obj[index];
        }
        return (*this);
      }

      template<typename R>
      Vector<T, Dim> & operator=(Vector_expression<R, Dim> && obj) {
        for(std::size_t index = 0; index < Dim; ++index) {
          data[index] = obj[index];
        }
        return (*this);
      }

      virtual const T operator[] (std::size_t index) const override {
        return data[index];
      }

      T & operator[] (std::size_t index) {
        return data[index];
      }

      virtual ~Vector() = default;
    };

    template<typename E1, typename E2, typename R, std::size_t Dim>
    class Vector_sum final : public Vector_expression<R, Dim> {
      private:
        const E1 & _lhs;
        const E2 & _rhs;
      public:
        Vector_sum() = delete;

        Vector_sum(const E1 & lhs, const E2 & rhs) :
            _lhs(lhs),
            _rhs(rhs)
        {}

        virtual const R operator[] (std::size_t index) const override {
          return _lhs[index] + _rhs[index];
        }

        virtual ~Vector_sum() = default;
    };

    template<typename R, std::size_t Dim>
    Vector_sum<Vector_expression<R, Dim>, Vector_expression<R, Dim>, R, Dim> operator+ (const Vector_expression<R, Dim> & lhs, const Vector_expression<R, Dim> & rhs) {
      return {lhs, rhs};
    }

  }
}
阿舍普勒

只需定义一个operator+允许不同参数类型的。一个问题是确定结果总和的元素类型。可能最好的选择是使用添加两个元素的结果。编写这种类型的一种方法是:

decltype(std::declval<const R1>() + std::declval<const R2>())

或者,如果您知道类型是内置算术类型,那将与

std::common_type_t<R1, R2>

或者使用尾随返回类型,我们可以利用函数参数来缩短std::declval表达式:

template<typename R1, typename R2, std::size_t Dim>
auto operator+ (const Vector_expression<R1, Dim> & lhs,
                const Vector_expression<R2, Dim> & rhs)
-> Vector_sum<Vector_expression<R1, Dim>, Vector_expression<R2, Dim>,
              decltype(lhs[0] + rhs[0]), Dim>
{
  return {lhs, rhs};
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章