ブースト::バリアントイテレータを使用して「パラメータを変換できません」
-
13-09-2019 - |
質問
私は同じ種類のオブジェクトを保存するイテレータの種類を取ることができます関数を作成します:
最初はstd::map
含むshared_ptr<Foo>
(FooMap
としてのtypedef-ED)であり、他にもstd::list
(shared_ptr<Foo>
)を含有FooList
である。
私の関数は、この(かなり単純化)のように見えます:
set<Foo> CMyClass::GetUniqueFoos(FooIterator itBegin, FooIterator itEnd)
{
set<Foo> uniques;
for(/**/;
apply_visitor(do_compare(), itBegin, itEnd); // equals "itBegin != itEnd"
apply_visitor(do_increment(), itBegin)) // equals "++itBegin"
{
// Exact mechanism for determining if unique is omitted for clarity
uniques.insert( do_dereference< shared_ptr<Foo> >(), itBegin) );
}
return uniques;
}
次のようにFooIteratorと訪問者が定義されています:
typedef
boost::variant<
FooMap::const_iterator,
FooList::const_iterator>
FooIterator;
struct do_compare : boost::static_visitor<bool>
{
bool operator() (
const FooMap::const_iterator & a,
const FooMap::const_iterator & b) const
{ return a != b; }
bool operator() (
const FooList::const_iterator & a,
const FooList::const_iterator & b) const
{ return a != b; }
};
struct do_increment: boost::static_visitor<void>
{
template<typename T>
void operator()( T& t ) const
{ ++t; }
};
template< typename Reference >
struct do_dereference: boost::static_visitor<Reference>
{
template<typename T>
Reference operator()( const T& t ) const
{ return *t; }
};
私は、このメールの添付ファイルの大半を得ました>。そのソリューションはまたMSaltersの答えに応じて、少し多すぎるように思われ、アダプタおよびポリシーを使用していますので、私は単純にそのコードをコピーしたくありません。特に、私はそれの一部を理解するように。
私はVS2008から次のコンパイラエラーを取得する上記のコードでは(これは私がここに投稿するにはあまりにも多くのビットがあると思い、合計で160の最初の数行ですが、私は場合はそれらを追加させていただきます誰かが)それをすべて見たいます:
1>c:\boost\boost\variant\detail\apply_visitor_binary.hpp(63) :
error C2664: 'bool CMyClass::do_compare::operator ()(
const std::list<_Ty>::_Const_iterator<_Secure_validation> &,
const std::list<_Ty>::_Const_iterator<_Secure_validation> &) const' :
cannot convert parameter 1 from 'T0' to
'const std::list<_Ty>::_Const_iterator<_Secure_validation> &'
1> with
1> [
1> _Ty=shared_ptr<Foo>,
1> _Secure_validation=true
1> ]
1> Reason: cannot convert from 'T0' to 'const std::list<_Ty>::_Const_iterator<_Secure_validation>'
1> with
1> [
1> _Ty=shared_ptr<Foo>,
1> _Secure_validation=true
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\boost\boost\variant\variant.hpp(806) : see reference to function template instantiation 'bool boost::detail::variant::apply_visitor_binary_invoke<Visitor,Value1>::operator ()<T>(Value2 &)' being compiled
1> with
1> [
1> Visitor=const CMyClass::do_compare,
1> Value1=T0,
1> T=T1,
1> Value2=T1
1> ]
[...]
私が間違って何をしているのですか?
解決
私はあなたのdo_compareのstatic_visitorに例が欠落している疑いがあります。思い出してくれるが、変異体は何かを持っているかもしれないので、あなたはFooMap :: const_iteratorのにFooList :: const_iteratorのを比較するような、すべての可能な組み合わせを必要とします。これは、コンパイラはそのような場合のために、いくつかの一致を見つけようとしている、とFooMapを変換することはできませんので、:: const_iteratorのをFooList :: const_iteratorのに文句を言っています。
それを打ち出します:
struct do_compare : boost::static_visitor<bool>
{
bool operator() (
const FooMap::const_iterator & a,
const FooMap::const_iterator & b) const
{ return a != b; }
bool operator() (
const FooList::const_iterator & a,
const FooList::const_iterator & b) const
{ return a != b; }
bool operator() (
const FooMap::const_iterator & a,
const FooList::const_iterator & b) const
{ return false; }
bool operator() (
const FooList::const_iterator & a,
const FooMap::const_iterator & b) const
{ return false; }
};
ここでテンプレートとバージョンです
template <typename A, typename B>
bool operator() (
const A & a,
const B & b) const
{ return false; }
template <typename A>
bool operator() (
const A & a,
const A & b) const
{ return a != b; }
これは、コモでコンパイルだが、私はそれが動作する100%ではないですので、いくつかのテストが必要です。クリーナー、より汎用的なコード以外の、それは限り、それが動作するよう、あらゆる効果を持つべきではありません。