const成员返回为非const

const member returned as non-const

本文关键字:const 返回 成员      更新时间:2023-10-16

在以下简单示例中

#include <vector>
#include <type_traits>
#include <typeinfo>
#include <iostream>
class Dumb {
    public:
        typedef const std::vector<double> result_type;
    private:
        result_type mat_;
    public:
        Dumb(const result_type& mat) : mat_(mat) {}
        const result_type& get() const {
          std::cout << "const return" << std::endl;
          return mat_;
        }
        result_type& get() {
          std::cout << "non-const return" << std::endl;
          return mat_;
        }
};

int main(int,char*[]){
    const std::vector<double> B(5,1.0);
    const Dumb d(B);
    d.get();
    std::cout << "d " << typeid(d).name() << " "
          << std::is_const<decltype(d)>::value << std::endl;
    std::cout << "d.get() " << typeid(d.get()).name() << " "
          << std::is_const<decltype(d.get())>::value << std::endl;
}

产生输出

const return
d N12_GLOBAL__N_14DumbE 1
d.get() NSt3__16vectorIdNS_9allocatorIdEEEE 0

,例如

const return
double (anonymous namespace)::Dumb 1
d.get() std::__1::vector<double, std::__1::allocator<double> > 0

d.get()为什么返回非const向量?

decltype(d.get())是参考类型;参考类型不能被构成标记(尽管它们的基本对象类型可以是),因此is_const将是错误的。

如果您测试了基础对象类型std::remove_reference<decltype(d.get())>::type,则is_const应该为true。

it const

此处的错误是您要测试的方式。is_const只是告诉您参考类型不是const,这始终是正确的。

最好直接测试这些东西,例如通过尝试突变d.get()的结果:

#include <vector>
#include <iostream>
class Dumb
{
    public:
        typedef const std::vector<double> result_type;
    private:
        result_type mat_;
    public:
        Dumb(const result_type& mat) : mat_(mat) {}
        const result_type& get() const { return mat_; }
        result_type& get() { return mat_; }
};
int main(int, char*[])
{
    const std::vector<double> B(5,1.0);
    const Dumb d(B);
    d.get().push_back(6);
}
// error:
//  no matching function for call to 'std::vector<double>::push_back(int) const'

从此,很明显d.get() const std::vector<double>&