0

私は私を怒らせる問題に遭遇しました。followinタイマーエントリ構造を使用してタイマーを実装しました。

typedef std::multimap<boost::posix_time::ptime, events::ITimeout*> TEntryMap;
TEntryMap entries_;

そして、次のようにして要素をマルチマップに挿入します。

boost::posix_time::ptime tTimeout = boost::posix_time::microsec_clock::local_time() + boost::posix_time::milliseconds(timeout);
entries_.insert(std::make_pair(tTimeout, ptr)); // ptr is the events::ITimeout object

そして、1つの翻訳ユニット(cppファイル)で完全に機能します。ただし、この機能を別のcppファイルに移動する必要があり、コンパイルエラーが発生します。

1>Build started 2013-02-07 15:38:18.
1>ClCompile:
1>  EventDispatcher.cpp
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(260): error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const boost::posix_time::ptime' (or there is no acceptable conversion)
1>          ....\boost\boost\date_time\posix_time\ptime.hpp(57): could be 'boost::posix_time::ptime &boost::posix_time::ptime::operator =(const boost::posix_time::ptime &)'
1>          while trying to match the argument list '(const boost::posix_time::ptime, const boost::posix_time::ptime)'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(259) : while compiling class template member function 'std::pair<_Ty1,_Ty2> &std::pair<_Ty1,_Ty2>::operator =(std::pair<_Ty1,_Ty2> &&)'
1>          with
1>          [
1>              _Ty1=const boost::posix_time::ptime,
1>              _Ty2=events::ITimeout *
1>          ]
1>          ....\eventdispatcher.cpp(72) : see reference to class template instantiation 'std::pair<_Ty1,_Ty2>' being compiled
1>          with
1>          [
1>              _Ty1=const boost::posix_time::ptime,
1>              _Ty2=events::ITimeout *
1>          ]
1>

私は無知で、これに2時間苦労しています。動作している実装と動作していない実装の間に違いは見られません。同じ構成、同じマルチマップ、同じインクルード、同じすべて!;(

4

1 に答える 1

0

問題の原因を突き止めましたが、VS2010 C++ コンパイラのバグのような匂いがします (std::remove_if を使用する場合)。コンストラクトを使用したクラスでの後の関数実装では、マップ内の要素を次のように削除しようとしました。

void removeEntry(events::ITimeout* p)
{
    std::remove_if(entries_.begin(), entries_.end(),
        [&](TEntryMap::value_type& entry)->bool
        { 
             return (entry.second == p);
        }
    );
}

そのコードを次のように変更します。

void removeEntry(events::ITimeout* p)
{
    TEntryMap::iterator it = std::find_if(entries_.begin(), entries_.end(),
        [&](TEntryMap::value_type& entry)->bool
        { 
             return (entry.second == p);
        }
    );
    if (it != entries_.end()) entries_.erase(it);
}

挿入コードを機能させます。図に行きます。ラムダ クロージャの代わりに構造体ベースの述語を使用しても、std::remove_if では機能しないことに注意してください...

于 2013-02-08T08:22:23.250 に答える