C ++“ smart” stl算法的谓词
题
我需要为stl算法设计谓词,例如find_if,count_if。
namespace lib
{
struct Finder
{
Finder( const std::string& name ):
name_( name )
{
}
template< typename TElement >
bool operator( const TElement& element )
{
return element.isPresent( name_ );
}
/* template< typename TElement >
bool operator( const TElement& element )
{
const Data& data = element.getData();
return data.isPresent( name_ );
}*/
};
}
但是我需要它根据TElement中某些特定方法的存在而拥有不同的operator()。就好像它有“getData”一样我想检查一下这些数据,如果没有,我会做其他一些操作。
我知道SFINAE。但我在项目上没有boost ::。 因此,要么有一些简单的模板实现“has_method”,或者你知道其他一些设计方案。
我无法指出特定的类型并且只是重载,因为我想把这个Predicate放到项目库中,它不知道带有“getData”的那些特定类。方法
只要没有名称空间,具有类特征的解决方案就很好。在“lib”中的谓词查找器带有“getData”的名称空间和类是在“程序”中命名空间。
感谢。
解决方案
为什么要使用模板mathods?如果有很多类类型,只需使用您希望基于它的特定类或公共基类。
e.g。
struct Finder
{
Finder( const std::string& name ):
name_( name )
{
}
bool operator( const IsPresentBaseClass& element )
{
return element.isPresent( name_ );
}
bool operator( const GetDataBaseClass& element )
{
const Data& data = element.getData();
return data.isPresent( name_ );
}
};
如果这种模式在不同的类类型中发生很多,并且在使用谓词之前就知道了类型,那么你可以模拟谓词本身。
e.g。
template<class T1, class T2>
struct Finder
{
Finder( const std::string& name ):
name_( name )
{
}
bool operator( const T1& element )
{
return element.isPresent( name_ );
}
bool operator( const T2& element )
{
const Data& data = element.getData();
return data.isPresent( name_ );
}
};
或者您可以使用的另一种方法是使用某种类特征来保存信息。
e.g。
struct UseIsPresent
{
template<class T>
static bool CompareElement( const T& element, const std::string& name )
{
return element.isPresent( name );
}
};
struct UseGetData
{
template<class T>
static bool CompareElement( const T& element, const std::string& name )
{
const Data& data = element.getData();
return data.isPresent( name );
}
};
// default to using the isPresent method
template <class T>
struct FinderTraits
{
typedef UseIsPresent FinderMethodType;
};
// either list the classes that use GetData method
// or use a common base class type, e.g. UseGetData
template <>
struct FinderTraits<UseGetData>
{
typedef UseGetData FinderMethodType;
};
struct Finder
{
Finder( const std::string& name )
: name_( name )
{
}
template<class T>
bool operator()( const T& element )
{
return FinderTraits<T>::FinderMethodType::CompareElement<T>(element, name_);
}
std::string name_;
};
所有这些方法的缺点是,在某些时候你需要知道能够将它们分成哪种方法的类型。
其他提示
您可以查看 Veldhuizen的主页用于 switch
模板。您可以使用它来选择确切的运算符吗?
让您的类型来自“功能类型” (例如类型“has_function1”)将作为java接口使用,并且您有机会,因为SFINAE可用于测试是否可以将一种类型转换为另一种类型。
如果您有兴趣,我可以查看并给您更详细的答案。
编辑: 我知道你说你没有可用的Boost库,但是有什么东西阻止你获得boost :: is_convertible工作所需的几个文件吗?编译时没有特别的东西!
提升不是魔术;使用SFINAE非常简单:
template< typename TElement >
bool operator( const TElement& element, ... )
{
return element.isPresent( name_ );
}
template< typename TElement >
bool operator( const TElement& element, const Data& data = element.getData())
{
return data.isPresent( name_ );
}
如果不编译,SFINAE将删除第二个重载。重载分辨率将选择第二个,如果它编译,因为...是一个更糟糕的匹配。