简体   繁体   English

C++ SFINAE:如果可能,对标准集合进行排序

[英]C++ SFINAE: sort a std collection if possible

I've seen various SFINAE-related answers regarding calling a function conditionally depending on whether or not a class has a certain function.我已经看到了各种与 SFINAE 相关的答案,关于有条件地调用 function,具体取决于 class 是否具有一定的 function。 They're mostly different from what I'm trying to achieve, so I haven't been able to translate it into my project.它们与我想要实现的目标大不相同,因此我无法将其转化为我的项目。

I have an algorithm that iterates through a collection and does some stuff.我有一个算法可以遍历一个集合并做一些事情。 The algo relies on the collection being sorted.算法依赖于被排序的集合。 I want to be able to feed the algo either a set (which is sorted internally and does NOT have a "sort" function), or a list (which is not sorted, and DOES have a "sort" function).我希望能够为算法提供一个集合(内部排序并且没有“排序”功能)或列表(没有排序,并且有一个“排序”功能)。

I want to make my solution more generic than just for set or list.我想让我的解决方案比集合或列表更通用。 I want there to be a single function which will call the sort method on the template type if it exists, and not otherwise.我希望有一个 function 如果模板类型存在,它将调用模板类型的排序方法,否则不调用。

template <class Container>
void algo(Container container) {
  container.sort();
  algoHelper(container);
}

template <class Container>
void algo(Container container) {
  algoHelper(contiainer);
}

I thought if I feed a std::set to the first function it'll fail to instantiate because std::set::sort doesn't exist, then it'll attempt to instantiate the second one and succeed.我想如果我将 std::set 提供给第一个 function 它将无法实例化,因为 std::set::sort 不存在,那么它将尝试实例化第二个并成功。

I also tried adding std::enable_if to the template of the first function:我还尝试将 std::enable_if 添加到第一个 function 的模板中:

template <typename Container,
          typename std::enable_if_t<std::is_member_function_pointer<decltype(&Container::sort)>::type>>

but got:但得到:

error: no matching function for call to 'algo(std::__cxx11::list<int>)'

Not sure how to proceed.不知道如何进行。 Thanks!谢谢!

Answering my own question.回答我自己的问题。

Thanks uneven_mark for pointing out the possible duplicate ( Is it possible to write a template to check for a function's existence? ).感谢不均匀标记指出可能的重复项( 是否可以编写模板来检查函数的存在? )。 I'm using GCC 6.x which supports C++ 17 but not if-constexpr, so that solution didn't work entirely.我正在使用支持 C++ 17 但不支持 if-constexpr 的 GCC 6.x,因此该解决方案无法完全工作。

Taking that answer as inspiration, here's my solution:以这个答案为灵感,这是我的解决方案:

template<typename T>
using sort_t = decltype( std::declval<T&>().sort() );

template<typename T>
constexpr bool has_sort = std::experimental::is_detected_v<sort_t, T>;

template <class Container>
std::enable_if_t<has_sort<Container>, void>
algo(Container container) {
  container.sort();
  algoHelper(container);
}

template <class Container>
std::enable_if_t<!has_sort<Container>, void>
algo(Container container) {
  algoHelper(contiainer);
}

As uneven_mark points out, I'll need to handle the case where a container is both unsorted and doesn't have a sort function.正如不均匀标记指出的那样,我需要处理容器既未排序又没有排序 function 的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM