我想创建一个函数,它可以采用存储相同类型对象的不同类型的迭代器:
第一个是 std::map
包含 shared_ptr<Foo>
(类型定义为 FooMap
),另一个是 std::list
其中还包含 shared_ptr<Foo>
(FooList
)。
我很喜欢the solution MSalters suggested for a similar question并尝试实现 boost::variant
迭代器,函数将获取它作为参数从第一个迭代到第二个。
我的函数看起来像这样(简化了不少):
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; }
};
我得到了上面的大部分from the attachment of this mail .该解决方案还使用了适配器和策略,根据 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 中遗漏了案例。请记住,变体可能包含任何内容,因此您需要所有可能的组合,例如将 FooList::const_iterator 与 FooMap::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; }
它在 comeau 上编译,但我不是 100% 它会工作,所以需要一些测试。除了更简洁、更通用的代码外,它应该不会有任何影响,只要它能工作。
关于c++ - "Cannot convert parameter"使用 boost::variant 迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/970382/