gpt4 book ai didi

C++ "smart"STL 算法的谓词

转载 作者:搜寻专家 更新时间:2023-10-31 01:23:52 24 4
gpt4 key购买 nike

我需要为 find_if、count_if 等 STL 算法设计谓词。

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 中某些特定方法的存在而具有不同的运算符 ()。例如,如果它有“getData”,我想检查该数据,如果没有,我会执行一些其他操作。

我知道 SFINAE。但是我没有 boost::项目。因此,要么有模板“has_method”的一些简单实现,要么您知道一些其他设计解决方案。

我不能指向特定类型并简单地重载,因为我想将此 Predicate 放入项目库之一,它不知道那些具有“getData”方法的特定类。

只要没有 namespace ,具有类特征的解决方案就很好。 “lib”命名空间中的 Predicate Finder 和带有“getData”的类位于“program”命名空间中。

谢谢。

最佳答案

为什么要使用模板方法?如果有很多类类型,只需使用您想要作为其基础的特定类或公共(public)基类。

例如

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_ );
}
};

如果这种模式在不同的类类型中经常发生,并且您在使用谓词之前知道这些类型,您可以模板化谓词本身。

例如

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_ );
}
};

或者您可以使用的另一种方法是使用某种类特征来保存信息。

例如

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_;
};

所有这些方法的缺点是在某些时候您需要知道类型才能将它们拆分为要使用的方法。

关于C++ "smart"STL 算法的谓词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/600175/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com