2016-08-05 17 views
2

std::vectorの要素への参照をnon-constへ返す方法を理解するのに苦労しています。私が行くよ何の簡単な例では、ベクトル要素への非const参照を返すConstメソッド

template<class T> 
class MyClass 
{ 
public: 
MyClass : myVec(3) 
{ 
} 

T& x() const 
{ 
    return *(myVec.data())[0] 
} 

std::vector<T> myVec; 
} 

私はつもりだ行動は、私は、次のようなものを行うことができるようにしたいということで、ある

MyClass obj<double>; 
obj.x() = 3.3; 
assert(obj.x()==3.3) 

Eigen同じ種類の動作を提供しますが、動作させる方法を理解できませんでした。

+0

@jlackなぜ定数でないオブジェクトへの参照を返そうとしているのかは不明です。 –

+1

'x'はなぜconstですか?あなたが変異アクセサーを持っているなら、それはconstであってはいけません。 – NathanOliver

+0

コンテナ内のアイテムがコンテナであるために定数である必要があるかどうかは議論の余地があります。非定数ポインタの定数コンテナがある場合、それは根本的に異なるのでしょうか?あなたは、その値が何であるのではなく、どの項目が存在するかにのみ適用するものとしてconstを参照することができます。 – nate

答えて

10

const_castを使用できます。ここでの作業は(使用状況に応じて)行います。しかし、この場合(そしてほとんどの場合)、あなたはそれを必要としません。

constメンバー以外の関数のオーバーロードを追加できます(また、追加する必要があります)。 constメンバ関数はconstへの参照を返し、非constメンバ関数は非constへの参照を返します。適切なものがoverload resolutionによって呼び出されます。

const T& x() const 
{ 
    return myVec[0]; 
} 
T& x() 
{ 
    return myVec[0]; 
} 
2

標準ライブラリのコンテナは、コンテナのコンテナを値自体に拡張します。あなたのクラスはx()で一定なので、ベクトルもそうです。 const_castを使用して、アクセサの項目からconstを削除することができます。一般的に

return const_cast <T&> (*(myVec.data())[0]); 

constがあなたを保護することがあるので、これは、悪い習慣と考えられています。これらの保護をバイパスすると、コードを推論するのが難しくなります。