【问题标题】:c++ subscript operator to underling class vectorc ++下标运算符到基础类向量
【发布时间】:2017-08-30 21:19:21
【问题描述】:

所以我正在尝试创建一个 vec 类,我可以稍后对其进行 vec 数学运算。

在我开始对其实施实际程序之前工作得很好。

类vecn:

#include <vector>

template <typename T>
class vecn
{
public:
    vecn() {    }
    template <typename... Args>
    vecn(Args&&... args)
    {
        addtovector(args...);
    }

    friend std::ostream& operator<<(std::ostream& os, const vecn<T>& obj)
    {
        os << "{";
        for (auto it = obj.contents.begin(); it < obj.contents.end(); it++) {
            os << *it;
            if (it != obj.contents.end() -1)
            {
                os << ",";
            }
        }
        os << "}";
        return os;
    }

    template<typename T>
    vecn<T>& operator=(const vecn<T>& v) {
        contents = v.contents;
        return *this;
    }

    unsigned int size() const
    {
        return contents.size();
    }

    vecn<T> operator+(const vecn<T>& v1) {
        vecn<T> v2();
        for (unsigned int i = 0; i < size();i++)
        {
            v2[i] = v1[i] + this->contents[i];
        }
        return v2;
    }

    T& operator[](size_t Index)
    { 
        if (Index > contents.size() -1)
        {
            contents.resize(Index + 1);
        }
        return contents.at(Index);
    }

    const T& operator[](size_t Index) const
    {
        return contents.at(Index);
    }

private:
    template <typename... Args>
    void addtovector(T& first, Args&&... args)
    {
        addtovector(first);
        addtovector(args...);
    }

    void addtovector(T& item)
    {
        contents.push_back(item);
    }
    std::vector<T> contents;
};

现在我在使用下标运算符访问下级向量时遇到问题,无论我如何设计它,它都无法正常工作。通常会导致

Error   C2109   subscript requires array or pointer type

通过谷歌搜索错误,我应该返回一个指向带有下标的数组的指针。我做的。

我有什么遗漏吗?

主要:

vecn<int> v(1,2);
vecn<int> b(3, 4, 5);
std::cout << v + b;

预期输出:

{4,6,5}

【问题讨论】:

  • 一开始你不应该在operator=中使用template&lt;typename T&gt; 关键字

标签: c++ vector operator-overloading


【解决方案1】:

GCC 准确地告诉我出了什么问题:

error: declaration of template parameter ‘T’ shadows template parameter

(对于您的赋值运算符)

然后:

warning: pointer to a function used in arithmetic [-Wpointer-arith]
         v2[i] = v1[i] + this->contents[i];

(您已将v2 声明为返回vecn&lt;T&gt; 的函数,删除括号)

最后,修复你的operator+,因为它会尝试访问一个空的v2 向量的元素,并且如果它们的大小不相等,则访问超出v1this-&gt;contents 中较小者的范围。


在我看来,你为这么简单的事情写了很多不必要的代码。你不需要addtovector,只需像这样展开参数包:

contents{std::forward<Args>(args)...}

在成员初始化列表中。你根本不需要定义operator=,把它留给编译器。并尝试implement operator+ in terms of operator+=

【讨论】:

  • 想知道为什么视觉工作室不同意给我这些错误。
【解决方案2】:

尽管有所有其他的东西,但你的代码中有一件相当令人毛骨悚然的东西

if (Index > contents.size() -1)

您永远不应该用算术运算替换布尔运算符的正确选择! std::vector.size() 返回 size_t (在大多数系统上是 unsigned long ),只有您自制的 size() 返回 int,它不应该因为负尺寸没有意义。

现在 0 - 1 不会产生负数,0 是 size_t 而是一些 huuuge:18446744073709551615 (0xffffffffffffff)。

所以 size()=0

if (Index > contents.size() -1)

永远不会是真的,你的 vec 不会像你想要的那样在访问 vec[0] 时增长。只需使用

if (Index >= contents.size())

这正是你的意思。

【讨论】:

    【解决方案3】:

    您的问题很可能是您使用了vecn&lt;T&gt; v2(); 而不是vecn&lt;T&gt; v2;,但您的解决方案中还有其他不好的地方。这是一些重构:

    template <typename T>
    class vecn {
    public:
        vecn() {}
        template <typename... Args>
        vecn(Args&&... args)
        {
            addToVector(args...);
        }
    
        friend std::ostream& operator<<(std::ostream& os, const vecn<T>& obj)
        {
            os << "{";
            for (auto it = obj.contents.begin(); it < obj.contents.end(); it++) {
                os << *it;
                if (it != obj.contents.end() - 1)
                    os << ",";
            }
            os << "}";
            return os;
        }
    
        // you don't need this
        // template<typename T>
    
        // also whole method is unnecessary
        //    vecn<T>& operator=(const vecn<T>& v)
        //    {
        //        contents = v.contents;
        //        return *this;
        //    }
    
        // use size_t
        /*unsigned int*/ size_t size() const
        {
            return contents.size();
        }
    
        vecn<T> operator+(const vecn<T>& other) const
        {
            vecn<T> result;
            size_t resultSize = std::max(other.size(), size());
            result.contents.reserve(resultSize);
    
            for (size_t i = 0; i < resultSize; ++i) {
                T value = {};
                if (i < other.size())
                    value += other.contents[i];
                if (i < size())
                    value += contents[i];
    
                result.contents.push_back(value);
            }
    
            return result;
        }
    
        T& operator[](size_t index)
        {
            return contents.at(index);
        }
    
        const T& operator[](size_t index) const
        {
            return contents.at(index);
        }
    
    private:
        template <typename... Args>
        void addToVector(T& first, Args&&... args)
        {
            addToVector(first);
            addToVector(args...);
        }
    
        void addToVector(T& item)
        {
            contents.push_back(item);
        }
        std::vector<T> contents;
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-10
      • 2012-09-29
      相关资源
      最近更新 更多