[英]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.