1

次のコードを検討します。

#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を設定できないのはなぜですか?

4

2 に答える 2

5

const double*&へのポインタへの参照const doubleです。

const double* constへのconstポインタconst doubleです。

これは、定数ポインタを返す必要があることを意味します。

inline Type* const & getptrc() const {return _ptr;}

constonメソッドは、データメンバーを変更しないことを意味します。そのコントラクトを実行するには、定数ポインターを返す必要があります。そうしないと、データメンバーを変更する可能性があるためです_ptr。ただし、を使用する他のケースではgetvalc、を返すことでその契約をすでに履行していますconst double

于 2012-08-29T02:04:40.827 に答える
1

MyClass<const double>、名前Typeはを指しconst doubleます。したがってgetvalc()、を返すメンバー関数Type&は問題ありません。それはを返し、const double&その_val参照を介して変更することはできません。

Type*&;には別の間接層があります。ですTypeconst double、それを指すポインタは変更可能です。これが、コンパイラが文句を言う理由_ptrです。constメンバー関数内のconstですが、関数はそれを変更可能なポインタとして返そうとします。

于 2012-08-29T02:07:58.097 に答える