非Const对象的Const向量



在接口中定义函数:

virtual void ModifyPreComputedCoeffs ( std::vector < IndexCoeffPair_t > & model_ ) = 0;

我们想要指定vector model_不应该在push_back等操作的意义上被改变,但是model_中的IndexCoeffPair_t结构对象可以被改变。我们应该如何指定呢?

virtual void ModifyPreComputedCoeffs ( const std::vector < IndexCoeffPair_t > & model_ ) = 0;

不将vector对象传递给函数,而是按照标准库的做法,传递一对迭代器。

virtual void ModifyPreComputedCoeffs ( std::vector < IndexCoeffPair_t >::iterator & model_begin, std::vector < IndexCoeffPair_t >::iterator & model_end )

c++的常量正确性概念在我看来被高估了。你刚刚发现的是它有一个很大的限制:它不能按组成比例缩放。为了能够创建非const对象的const向量,您需要实现自己的vector类型。请注意,例如,即使是标准库也必须为const_iterator引入新的类型。

我的建议是在你不得不使用的地方使用const-正确性,而不是在任何你可以使用的地方。从理论上讲,const正确性应该对程序员有帮助,但由于语法的原因,代价非常高,而且非常原始(只有一个位,不能按组合扩展,甚至需要代码复制)。

根据我的经验,这个所谓的大帮助并不是真的那么大…它捕获的大多数错误都与常量正确性机制本身有关,而与程序逻辑无关。

有没有想过为什么大多数语言(包括在c++之后设计的语言)没有实现这个想法?

这可能在c++ 14中作为std::dynarray.

实际上,如果大小在编译时是固定的,你可以使用std::array。但它可能更适用于嵌入式编程,缓冲区,矩阵等,因为通常你不知道所需的大小,直到运行时,或者你希望它是可配置的。

如果您能够修改IndexCoeffPair_t,您可以添加一些const成员函数,并通过使用mutable关键字使成员可变来使用它们来更改它的一些成员。这是一种hack,因为你现在可以改变任何const IndexCoeffPair_t的内容。

的例子:

class IndexCoeffPair_t {
public:
    void changeX(int newVal) const {
        x = newVal;
    }
private:
    mutable int x;
};

以下是MahlerFive的一般性回答:

template<typename T>
class Mutable {
    mutable T m_val;
public:
    constexpr Mutable(T const& val) : m_val(val) { }
    constexpr Mutable(T&& val) : m_val(val) { }
    // note: all member functions are `const`
    constexpr Mutable const& operator=(T const& val) const {
        m_val = val;
        return *this;
    }
    constexpr Mutable const& operator=(T&& val) const {
        m_val = val;
        return *this;
    }
    constexpr operator T&() const {
        return m_val;
    }
};

你可以在你的代码中使用std::vector<Mutable<T>> const,它会像预期的那样运行。

您可以尝试创建const std::vector<YouType*>。你不能改变矢量,但你可以改变矢量内的物体。但是要准确,因为你修改的是原始对象,而不是副本。

使用智能指针或原始指针取决于你的用例:你拥有向量或只是观察者的向量。

最新更新