Можно ли (и как) добавить проверку контракта типа для параметра функции шаблона C ++?

Например, я хочу реализовать свою собственную универсальную функцию сортировки, я хочу, чтобы тип, который будет передан, был Indexableи элемент внутри будет Comparable

template <typename Cont>
**type_check: Cont is Indexable, Cont::Element is Comparable**
void my_sort(Cont& cont){
// do sorting work
}

Когда я делаю my_sort(vector<int>{1,6,5,4}) было бы хорошо

Но когда my_sort(linkedlist<int>{1,6,5,4}) потерпел бы неудачу во время компиляции / выполнения, потому что linkedlist не является Indexable,

Так есть ли способ сделать такого рода программирование контракта типа?

Постскриптум Я нахожусь в среде C ++ 11, но также приветствуется любое решение в более поздней версии C ++

0

Решение

С SFINAE вы можете сделать что-то вроде:

template <typename Cont>
auto my_sort(Cont& cont)
-> decltype(cont[42], // Indexable
void(), // That void to avoid evil overload of operator comma
std::declval<Cont::Element>() < std::declval<Cont::Element>(), // Comparable
void()) // That final void for the return type of sort
{
// do sorting work
}

std::enable_if является альтернативой ( decltype) если у вас есть готовые черты.

2

Другие решения

Как уже упоминалось в комментариях, как только Концепции ТС пробившись в стандарт C ++, вы сможете сделать это с помощью чего-то вроде:

template <typename T>
concept Sortable = requires(T t) {
{ t[0] < t[0] } -> bool
};

template <Sortable Cont>
my_sort(Cont& cont) {
// do sorting work
}

Live Demo

Старая версия Concepts TS реализована в GCC с флагом -fconcepts, но не будет в стандарте до C ++ 20. До тех пор, вы можете обойтись с трюками SFINAE:

template <typename Cont>
std::enable_if_t<std::is_convertible_v<decltype(std::declval<Cont>()[0] < std::declval<Cont>()[0]), bool>>
my_sort(Cont& cont) {
// ...
}

Это не удастся скомпилировать, если для данного Cont c, c[0] < c[0] либо недействителен, либо не конвертируется в bool,
Live Demo

1

По вопросам рекламы [email protected]