考虑以下代码:
#include <iostream>
#include <vector>
template<typename Type> class MyClass
{
public:
MyClass(Type* ptr) : _ptr{ptr}, _val{*ptr} {;}
inline Type*& getptr() {return _ptr;}
inline Type*& getptrc() const {return _ptr;}
inline Type& getval() {return _val;}
inline Type& getvalc() const {return _val;}
protected:
Type* _ptr;
Type _val;
};
int main()
{
std::vector<double> v = {0, 1, 2};
MyClass<const double> x(&v[0]);
x.getval();
x.getvalc(); // <- OK
x.getptr();
x.getptrc(); // <- ERROR : "invalid initialization of reference of type 'const double*&' from expression of type 'const double* const'"
return 0;
}
GCC会为getptrc函数invalid initialization of reference of type 'const double*&' from expression of type 'const double* const'
生成错误。但函数getvalc编译得很好。我不明白getvalc和getptrc之间的区别在于错误的起源。
错误的原因是什么?为什么我不能为返回指针引用的函数设置const?
答案 0 :(得分:5)
const double*&
是对指向const double
的指针的引用。
const double* const
是指向const double
的 const 指针。
这意味着你必须返回一个常量指针。
inline Type* const & getptrc() const {return _ptr;}
关于方法的 const
意味着您不会修改数据成员。要填充该合同,您必须返回一个常量指针,否则,您可以修改数据成员_ptr
。但是,在getvalc
的其他情况下,您已经通过返回const double
已完成该合同。
答案 1 :(得分:1)
在MyClass<const double>
中,名称Type
引用const double
。因此,返回getvalc()
的成员函数Type&
很好:它返回const double&
,并且无法通过该引用修改_val
。
Type*&
还有另一层间接;虽然Type
是const double
,但指向它的指针是可修改的;这就是编译器抱怨的原因:_ptr
是const成员函数中的const,但函数试图将其作为可修改的指针返回。