C++ SFINAE:如果可能,对标准集合进行排序
C++ SFINAE: sort a std collection if possible
我看到过各种与 SFINAE 相关的答案,这些答案是关于根据 class 是否具有特定函数来有条件地调用函数的。它们与我想要实现的目标大不相同,因此我无法将其转化为我的项目。
我有一个算法可以遍历一个集合并做一些事情。该算法依赖于正在排序的集合。我希望能够为算法提供一个集合(它在内部排序并且没有 "sort" 函数),或者一个列表(它没有排序,并且确实有一个 "sort" 函数) .
我想让我的解决方案比集合或列表更通用。我希望有一个单独的函数,如果模板类型存在,它将调用 sort 方法,否则不调用。
template <class Container>
void algo(Container container) {
container.sort();
algoHelper(container);
}
template <class Container>
void algo(Container container) {
algoHelper(contiainer);
}
我认为如果我将 std::set 提供给第一个函数,它将无法实例化,因为 std::set::sort 不存在,然后它将尝试实例化第二个函数并成功。
我也试过在第一个函数的模板中添加std::enable_if:
template <typename Container,
typename std::enable_if_t<std::is_member_function_pointer<decltype(&Container::sort)>::type>>
但得到了:
error: no matching function for call to 'algo(std::__cxx11::list<int>)'
不确定如何进行。谢谢!
回答我自己的问题。
感谢 uneven_mark 指出可能的重复项 (Is it possible to write a template to check for a function's existence?)。我正在使用支持 C++ 17 但不支持 if-constexpr 的 GCC 6.x,因此该解决方案无法完全工作。
以这个答案为灵感,这是我的解决方案:
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);
}
正如 uneven_mark 指出的那样,我需要处理容器既未排序又没有排序功能的情况。
我看到过各种与 SFINAE 相关的答案,这些答案是关于根据 class 是否具有特定函数来有条件地调用函数的。它们与我想要实现的目标大不相同,因此我无法将其转化为我的项目。
我有一个算法可以遍历一个集合并做一些事情。该算法依赖于正在排序的集合。我希望能够为算法提供一个集合(它在内部排序并且没有 "sort" 函数),或者一个列表(它没有排序,并且确实有一个 "sort" 函数) .
我想让我的解决方案比集合或列表更通用。我希望有一个单独的函数,如果模板类型存在,它将调用 sort 方法,否则不调用。
template <class Container>
void algo(Container container) {
container.sort();
algoHelper(container);
}
template <class Container>
void algo(Container container) {
algoHelper(contiainer);
}
我认为如果我将 std::set 提供给第一个函数,它将无法实例化,因为 std::set::sort 不存在,然后它将尝试实例化第二个函数并成功。
我也试过在第一个函数的模板中添加std::enable_if:
template <typename Container,
typename std::enable_if_t<std::is_member_function_pointer<decltype(&Container::sort)>::type>>
但得到了:
error: no matching function for call to 'algo(std::__cxx11::list<int>)'
不确定如何进行。谢谢!
回答我自己的问题。
感谢 uneven_mark 指出可能的重复项 (Is it possible to write a template to check for a function's existence?)。我正在使用支持 C++ 17 但不支持 if-constexpr 的 GCC 6.x,因此该解决方案无法完全工作。
以这个答案为灵感,这是我的解决方案:
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);
}
正如 uneven_mark 指出的那样,我需要处理容器既未排序又没有排序功能的情况。