仅在方法退出时使用模板



如果一个索引容器(map,set(调用tool::exists_in并具有它将调用第一个方法的find方法,有人能帮我完成这段代码吗。如果没有,请调用第二个方法。

namespace tools {
template<class TSource, class Ty>
auto exists_in(const TSource &source, const Ty &item)
->decltype(source->find())
{
return source.find() != source.end();
}
template<class TSource, class Ty>
auto exists_in(const TSource &source, const Ty &item)
{
return std::find(source.begin(), source.end(), item)
!= source.end();
}
}
int main()
{
std::set<int> vector= { 1, 2, 3 };
std::vector<int> set = { 1, 2, 3 };
std::cout<<tools::exists_in(vector, 1);///should execute the first **tools::exists_in** method
std::cout<<tools::exists_in(set, 1);///should execute the second **tools::exists_in** method
}

首先,第一个函数应该是

template<class TSource, class Ty>
auto exists_in(const TSource &source, const Ty &item)
-> decltype(source.find() != source.end())
//                        ^^^^^^^^^^^^^^^^
{
return source.find() != source.end();
}

以具有正确的返回类型。

然后你可能会使用一些"优先级">(对于最佳匹配(作为int...。我更喜欢具有继承性的显式(甚至可以使用无限优先级(:

struct low_priority {};
struct high_priority : low_priority {};
template<class TSource, class Ty>
auto exists_in(high_priority, const TSource &source, const Ty &item)
-> decltype(source->find(item) != source.end())
{
return source.find(item) != source.end();
}
template<class TSource, class Ty>
auto exists_in(low_priority, const TSource &source, const Ty &item)
{
return std::find(source.begin(), source.end(), item) != source.end();
}

template<class TSource, class Ty>
auto exists_in(const TSource &source, const Ty &item)
{
return exists_in(high_priority{}, source, item);
}

演示

您可以将has_find与SFINAE一起使用以启用/禁用过载,具体取决于TSource::find是否存在(请参阅Live示例(:

namespace tools {

template <typename T>
struct has_find
{
// use expression sfinae instead of obvious 
// template <typename C> static char test(decltype(&C::find)); - which doesn't seem to work correctly in this case
template <typename C> static char test( decltype(std::declval<C>().find(typename C::value_type{}))* );
template <typename C> static int test(...);    
enum { value = sizeof(test<T>(0)) == sizeof(char) };
};


template<class TSource, class Ty>
std::enable_if_t<has_find<TSource>::value, bool>
exists_in(const TSource &source, const Ty &item)
{
return source.find(item) != source.end();
}

template<class TSource, class Ty>
std::enable_if_t<! has_find<TSource>::value, bool>
exists_in(const TSource &source, const Ty &item)
{
return std::find(source.begin(), source.end(), item) != source.end();
}

}

编辑:添加静态断言以验证has_find是否正常工作:

using Set = std::set<int>;
using Vector = std::vector<int>;
using tools::has_find;
static_assert(has_find<Set>::value == true, "Error: Set::find not found!");
static_assert(has_find<Vector>::value == false, "Error: Vector::find found!");

最新更新