Enable_if problems



我想使用SFINAE原则来检查实例化的模板是否是随机访问迭代器。为此,我使用了std::enable_if,但是编译器抛出了一个错误:

不能与前面的'type-name'声明说明符组合

我该如何修复它?我真的需要你的帮助来解决这个问题。

template<class RandomAccessIterator, class Compare>
typename std::enable_if<std::is_same<std::random_access_iterator_tag, RandomAccessIterator>::value>
void quick_sort(RandomAccessIterator first, RandomAccessIterator last, Compare compare) {
sorting(first, last, 0, last - first - 1, compare);
}

我看到两个问题:

  • 你写的是std::enable_if<>而不是std::enable_if<>::type,这可能不是你想要做的。

  • (错误原因)有两种返回类型:std::enable_if<>void。你只能有一个返回类型

std::enable_if有第二个可选的类型参数,该参数是std::enable_if<>::type的类型。默认设置为void,因此您的返回类型已经从std::enable_if<>::type变为void。但是,由于您将enable_if放在返回类型中,我建议您显式指定返回类型为void

所以你的问题的解决方案看起来像这样:

template <class RandomAccessIterator, class Compare>
typename std::enable_if<
std::is_same<std::random_access_iterator_tag, RandomAccessIterator>::value,
void
>::type quick_sort(RandomAccessIterator first, RandomAccessIterator last, Compare compare) {
sorting(first, last, 0, last - first - 1, compare);
}

或者你可以在模板参数中使用std::enable_if:

template <
class RandomAccessIterator,
class Compare,
typename std::enable_if<
std::is_same<std::random_access_iterator_tag, RandomAccessIterator>::value,
std::nullptr_t
>::type = nullptr
>
void quick_sort(RandomAccessIterator first, RandomAccessIterator last, Compare compare) {
sorting(first, last, 0, last - first - 1, compare);
}

除了回答中提到的技术问题外,您的方法根本行不通。

std::is_same<std::random_access_iterator_tag, RandomAccessIterator>::value永远不会计算为真,因为迭代器不是迭代器标签。您需要通过std::iterator_traits(而不是SFINAE)使用标记调度来确定传入的迭代器是否是随机访问的。

参见cppreference的示例:https://en.cppreference.com/w/cpp/iterator/iterator_tags

试试这个:

template<class Iter, class Compare>
void quick_sort_impl(Iter first, Iter last, Compare compare, std::random_access_iterator_tag) {
sorting(first, last, 0, last - first - 1, compare);
}
template<class Iter, class Compare>
void quick_sort(Iter first, Iter last, Compare compare) {
quick_sort_impl(first, last, compare, typename std::iterator_traits<Iter>::iterator_category());
}

这样,如果你试图用非随机访问的迭代器调用quick_sort(),你将得到一个编译错误,因为缺少quick_sort_impl()重载非随机迭代器标签。如果想为其他类型的迭代器实现排序,只需根据需要为其他类型的迭代器标签重载quick_sort_impl()即可。

最新更新