const成员以非const形式返回

时间:2014-01-23 10:42:21

标签: c++ reference const

在下面的简单例子中

#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

e.g。

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

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

2 个答案:

答案 0 :(得分:3)

decltype(d.get())是参考类型;引用类型不能是const限定的(尽管它们的底层对象类型可以是),因此is_const将为false。

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

答案 1 :(得分:1)

const

这里的错误在于你正在测试的方式。 is_const只是告诉您引用类型不是const,这始终是真的。

直接测试这些东西比较好,例如by trying to mutate the result of 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>&