微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么数组是常量?

如何解决为什么数组是常量?

这个问题是 Why is alloca returning the same address twice? 的后续问题。我找到了一种使用数组为两个实例获取不同内存地址的方法

vml.h

#pragma once
#include <iostream>


namespace vml {
    // Vectors
    template <typename in_type,const int in_length>
    class vec {
    public:
        vec(in_type* in_data) {
            std::cout << data << std::endl;
            std::copy(in_data,in_data + in_length,data);
        }
        vec() {
            data = nullptr;
        }
        in_type& operator()(int index) const {
            _ASSERT(0 <= index && index < in_length);
            return data[index];

        }

    private:
        in_type data[in_length];
    };

ma​​in.cpp

#include <memory>
#include "vml.h"

int main() {
    int list[] = { 1,2,3 };
    int list2[] = {2,4,6 };

    vml::vec<int,3> a(list);
    vml::vec<int,3> b(list);

    a(1) = 3;
    
    return 0;
}

但是,当我运行代码时出现错误

Error C2440 'return': cannot convert from 'const in_type' to 'in_type &'

由于返回值是“data[index]”,这一定意味着它是常量,但是,我没有将其定义为常量,为什么会发生这种情况?

解决方法

您错过了 const 的返回类型中的 operator()()

in_type const & operator()(int index) const {
        _ASSERT(0 <= index && index < in_length);
        return data[index];
    }

当您使用 const 修饰符声明成员函数时,内部的所有类成员在使用时都变为常量

如果您想要非常量引用作为结果,则不应在该成员函数上使用 const 修饰符:

in_type & operator()(int index) {
    _ASSERT( 0 <= index && index < in_length);
    return data[index];
}
,

对于初学者来说这个构造函数

vec() {
    data = nullptr;
}

无效。数组是不可修改的左值。

这个成员函数

    in_type& operator()(int index) const {
        _ASSERT(0 <= index && index < in_length);
        return data[index];

    }

是一个常量成员函数。所以数组数据被认为是一个常量数组。

你可以像这样重载函数

    const in_type& operator()(int index) const {
        _ASSERT(0 <= index && index < in_length);
        return data[index];
    } 

    in_type& operator()(int index) {
        _ASSERT(0 <= index && index < in_length);
        return data[index];
    }

在本声明中的这种情况

a(1) = 3;

会调用非常量成员函数。

注意这个构造函数

    vec(in_type* in_data) {
        std::cout << data << std::endl;
        std::copy(in_data,in_data + in_length,data);
    }

不安全。并且至少参数应该有限定符 const

构造函数可以像这样声明

    vec( const in_type *in_data,size_t n );
,

要修复它,您必须重载 operator() 两次

in_type const &operator()(int index) const {
    _ASSERT(0 <= index && index < in_length);
    return data[index];
}
in_type &operator()(int index) {
    _ASSERT(0 <= index && index < in_lenght);
    return data[index];
}

你必须这样做,因为当你创建一个const对象时,该对象的任何成员都是const所以方法不能返回一个引用但它必须返回一个const引用,你可以使用这个方法,即使是非const方法,但是您不能更改成员的值,这就是您需要 in_type operator()(int index) 的原因。 重要的是,当您将方法限定为 const 时,这意味着它也可用于 const 对象,因此它必须像处理 const 一样处理任何成员。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。