在下面的简单例子中
#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()
会返回非常量向量?
答案 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>&
。