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

问题描述 投票:0回答:1

我已经看到了与SFINAE相关的各种答案,这些答案取决于类是否具有特定功能而有条件地调用函数。它们与我要达到的目标大部分不同,因此我无法将其转换为我的项目。

我有一个遍历集合并做一些事情的算法。该算法依赖于要排序的集合。我希望能够将一组(在内部进行排序且没有“排序”功能)或列表(未进行排序且没有“排序”功能)的算法提供给算法。

我想使解决方案更加通用,而不仅仅是集合或列表。我希望有一个函数可以对模板类型调用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>)'

不确定如何进行。谢谢!

c++ templates sfinae
1个回答
0
投票

回答我自己的问题。

感谢不均匀标记指出可能的重复项(Is it possible to write a template to check for a function's existence?)。我使用的是GCC 6.x,它支持C ++ 17,但不支持if-constexpr,因此该解决方案无法完全起作用。

以那个答案为灵感,这是我的解决方案:

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

正如不均匀标记指出的,我需要处理容器既未排序又没有排序功能的情况。

© www.soinside.com 2019 - 2024. All rights reserved.