3

型 (std::map) への const 参照を返すアクセサー関数があります ... ...

myMap_t const& getMap() const {return paramMap;} 

型にオーバーロードされた[]演算子があります。次に、次のような方法でゲッター関数から直接演算子を使用する構文は何です[]が、実際には機能します。

parameter = contextObj.getMap()[key];

エラーメッセージは次のとおりです。

context.cpp:35: error: passing   
  'const std::map<
     std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 
     float, 
     std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, 
     std::allocator<std::pair<
       const std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
       float> > >'
as 'this' argument of 
  '_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&)  
with 
  _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
  _Tp = float, 
  _Compare = std::less<std::basic_string<char, std::char_traits<char>,  td::allocator<char> > >, 
  _Alloc = std::allocator<std::pair<
    const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 
    float> >]' 
discards qualifiers
4

4 に答える 4

6

問題はoperator[]、マップ内が変更操作であり、マップへの const 参照で呼び出すことができないことです。変更する理由は、値への参照を返す必要があるためです。そのため、キーがまだコンテナに存在していない場合、そのキーによってアドレス指定された新しいデフォルトの構築された値を挿入し、それへの参照を返します。 .

const 参照があり、要素が存在するかどうかを判断する (またはそれにアクセスする) 場合は、それを使用std::map<>::findしてイテレータを返す必要があります。要素が存在しない場合、反復子の値は次のようになりますm.end()

于 2012-05-01T18:37:29.027 に答える
3

std::mapby const参照を返しますstd::map::operator[]が、マップを変更する必要がある場合があるため、const関数ではありません。
これを解決するには、次のいずれかを実行する必要があります。
(A).find代わりにを使用する[]

auto iter = contextObj.getMap().find( key );
if (iter != contextObj.getMap().end())
    param = iter->second;

(B)マップをnon constとして返します(非推奨)
(C)ラッパークラスを作成します(ほとんどの場合、価値がありません)

于 2012-05-01T18:38:46.893 に答える
1

const myMap_t&メソッドからを返しますgetMap()。エラーメッセージからmyMap_t、のtypedefがありますstd::map。マップにアイテムを挿入できるため、変更可能なオブジェクト(constでは呼び出せません)が必要です(指定されたキーを持つアイテムが存在しない場合は、マップに挿入され、そのオブジェクトへの参照が返されます)operator[]std::mapその問題を解決するには、2つのオプションがあります。

  • contextObj.getMap().find(key)の代わりにcontextObj.getMap()[key]、要素へのイテレータ(または要素map.end()が存在しない場合)を取得するために使用します
  • (constなしで) returnを実行して、呼び出すことができるmyMap_t&変更可能なオブジェクトを取得しますoperator[]
于 2012-05-01T18:39:15.820 に答える
1
context.cpp:35: error: passing   
  'const std::map<
     std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 
     float, 
     std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, 
     std::allocator<std::pair<
       const std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
       float> > >'
as 'this' argument of 
  '_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&)  
with 
  _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
  _Tp = float, 
  _Compare = std::less<std::basic_string<char, std::char_traits<char>,  td::allocator<char> > >, 
  _Alloc = std::allocator<std::pair<
    const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 
    float> >' 
discards qualifiers

std::basic_stringは を実装するために使用されるテンプレートstd::stringであり、実際にstd::stringは単に に基づくインスタンス化ですchar。したがって、最初に次のように置き換えます。

context.cpp:35: error: passing   
  'const std::map<
     std::string, 
     float, 
     std::less<std::string>, 
     std::allocator<std::pair<const std::string, float> >
  >'
as 'this' argument of 
  '_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&)  
with 
  _Key = std::string,
  _Tp = float, 
  _Compare = std::less<std::string>, 
  _Alloc = std::allocator<std::pair<const std::string> >' 
discards qualifiers

_Compareデフォルトを使用しているだけなので、マップの(比較関数) および_Alloc(アロケータ) 引数についてはあまり気にしません。_Keyこれらは無視して、との_Tp値をテンプレートの説明に代入しましょう。

context.cpp:35: error: passing   
  'const std::map<std::string, float>'
as 'this' argument of 
  'float& std::map<std::string, float>::operator[](const std::string&)  
discards qualifiers

では、もっと簡単に説明しましょう。の を使用していてoperator[]std::map<std::string, float>それを で使用しようとしていますconst std::map<std::string, float>(つまり、this呼び出しの引数として使用しているものです)。これは「修飾子を破棄」します。具体的には、const修飾子です。

コンパイラはoperator[]、マップの がマップを保持することを約束しないconst、つまり、マップを変更することが許可されていることを伝えています。これはコンパイル エラーです。マップが変更されないという組み込みアサーションを使用してコードが記述されているためです。

なぜマップが変わるのですか?さて、ドキュメントを見てください:

x がコンテナー内の要素のキーと一致する場合、関数はマップされた値への参照を返します。

x がコンテナー内のどの要素のキーとも一致しない場合、関数はそのキーを持つ新しい要素を挿入し、マップされた値への参照を返します。これにより、マップされた値が要素に割り当てられていない場合でも、常にマップ サイズが 1 増加することに注意してください (要素は既定のコンストラクタを使用して構築されます)。

(強調鉱山)。

要素の挿入は確かに変更です。

なぜこれを行うのですか?それについては、すでに質問があります。

于 2012-05-01T19:17:17.167 に答える