0

イテレータから通常のポインタを取得しようとしていますが、取得する型に関しては非常に特殊なことが起こっています。コードを投稿するだけです。これらの2つのスニペットは互いに等しいと思いますが、間違っているかどうか教えてください。スニペットに至るまでのコードは次のとおりです。

CallbackTrigger trigger(triggerParameters);
std::set<CallbackTrigger> triggerSet;
auto result = triggerSet.insert(trigger);

スニペットA:

auto whatIGet = &(*result.first);  // whatIGet is type:
                    // "const std::allocator<CallbackTrigger>::value_type *"

スニペットB:

auto arbitraryStep = *result.first; 
auto whatIWanted = &arbitraryStep;  // this is type "CallbackTrigger*"

この違いに問題があり、スニペットAでのコンパイルを拒否するコードは、ポインターをリストにプッシュしようとしたときです。

std::list<CallbackTrigger*> listing;
listing.push_back(whatIWanted); // compiles fine
listing.push_back(whatIGet);    // error: "cannot convert parameter 1 from 
                               // 'const CallbackTrigger* to 'CallbackTrigger *&&'"

ここで何が起こっているのですか?

4

2 に答える 2

1

c ++ 11標準によると:

template<class T> class allocator {
  ...
  typedef T value_type;
  ...
};

したがってconst std::allocator<CallbackTrigger>::value_type *、と同じconst CallbackTrigger*です。の要素はset<CallbackTrigger>const CallbackTriggerであるため、セットの要素へのポインターを直接取得しようとすると、それが取得されます。

スニペットの場合、BarbitraryStepはタイプCallbackTrigger*result.firstなりますconst CallbackTrigger。これは、タイプ控除のためにconstが削除されるためです。したがって&arbitraryStep、タイプですCallbackTrigger*(の欠如に注意してconstください)。whatIWantedまた、これはローカル変数(arbitraryStep)へのポインタであり、セット内のオブジェクトではないことに注意してください。したがって、それを使用しても、希望する動作が得られない場合があります。

これを考慮すると、リストのタイプをに変更する必要があることは明らかですlist<const CallbackTrigger*>

于 2012-07-29T17:51:22.230 に答える
0

std::set非constエイリアスを介してのコンテンツにアクセスすることはできません。これを達成するために発見した可能性のある手段は、標準ライブラリ実装の単なるバグであり、それを変更すると、未定義の動作につながる可能性があります。

あなたのwhatIWantエイリアスはset、スタックに作成したコピーにさえ含まれていません。

于 2012-07-29T17:48:47.673 に答える