代码之家  ›  专栏  ›  技术社区  ›  user1683586

使用复制构造函数启用_if

  •  8
  • user1683586  · 技术社区  · 7 年前

    我正在努力 std::enable_if 第一次和挣扎。如有任何指导,我们将不胜感激。

    vector 类,我想为其定义一个复制构造函数,但其行为取决于向量的相对大小:

    1. 只需将数据复制到较小或相同大小的向量中
    2. 将数据复制到较大的向量中,然后用零填充其余的向量

    课程为:

    template <size_t _Size>
    class Vector
    {
        double _data[_Size];
    
    public:
        Vector()
        {
            std::fill(_data, _data + _Size, 0.0);
        }
    
        const double* data() const
        {
            return _data;
        }
    
        // ...
    };
    

    复制构造函数应该支持这样的操作:复制 v3 进入 v2

    Vector<3> v3;
    Vector<2> v2(v3);
    

    我尝试了行为1的复制构造函数。就像这样,它编译:

    template <size_t _OtherSize,
    typename = typename std::enable_if_t<_Size <= _OtherSize>>
    Vector(const Vector<_OtherSize>& v) : Vector()
    {
       std::copy(v.data(), v.data() + _Size, _data);
    }
    

    但编译器无法将其与行为2区分开来。即使 enable_if

    template <size_t _OtherSize,
    typename = typename std::enable_if_t<_OtherSize < _Size>>
    Vector(const Vector<_OtherSize>& v) : Vector()
    {
        std::copy(v.data(), v.data() + _OtherSize, _data);
        std::fill(_data + _OtherSize, _data + _Size, 0.0);
    }
    

    我也试过推杆 启用_if _OtherSize

    template <size_t _OtherSize>
        Vector(const typename std::enable_if_t<_Size <= _OtherSize, 
        Vector<_OtherSize>> & v)
        : Vector()
        {
            std::copy(v.data(), v.data() + _Size, _data);
        }
    

    怎么做(使用 启用_if ,不是简单的 if 声明)?

    2 回复  |  直到 3 年前
        1
  •  7
  •   ildjarn    7 年前

    忽略默认值 二者都 在这些构造函数中

    template <size_t N, typename>
    Vector(const Vector<N>&)
    

    一、 他们最终是一样的。

    区分它们的一种方法是使模板参数类型直接依赖于 enable_if

    template <size_t _OtherSize,
        std::enable_if_t<(_Size <= _OtherSize), int> = 0>
        Vector(const Vector<_OtherSize>& v) : Vector()
        {
            std::copy(v.data(), v.data() + _Size, _data);
        }
    
    template <size_t _OtherSize,
        std::enable_if_t<(_OtherSize < _Size), int> = 0>
        Vector(const Vector<_OtherSize>& v) : Vector()
        {
            std::copy(v.data(), v.data() + _OtherSize, _data);
            std::fill(_data + _OtherSize, _data + _Size, 0.0);
        }
    

    顺便说一句,名字像 _Size _OtherSize 保留用于实现,因此用户代码丢失下划线和/或大写字母是非法的。

    此外,正如@StoryTeller所暗示的,当 _OtherSize == _Size Vector s、 因此无论如何,在过载解决过程中都不会选择它,但最好通过切换来明确意图 <= < .

        2
  •  4
  •   cigien    3 年前

    不要使用这样的名称 _Cap 因为 它们是保留的。不要模仿标准/系统标头内部命名约定。

    template <size_t O>
    Vector(const Vector<O>& v) : Vector()
    {
      constexpr auto to_copy = (std::min)( O, Size );
      constexpr auto to_fill = Size-to_copy;
      auto const* src=v.data();
      std::copy(src, src + to_copy, _data);
      std::fill(_data + to_copy, _data + to_copy+to_fill, 0.0);
    }
    Vector(const Vector& v) = default;
    

    std::fill 使用调用 (foo, foo, 0.0)