С++ менее подробный способ ввода аргумента шаблона

Я практикую учебник по алгоритмам и современное кодирование на C++. Я написал краткий тест, который проверяет функции сортировки следующим образом: (Я знаю, что using namespace std; не рекомендуется использовать в производстве, поэтому, пожалуйста, не советуйте по этому поводу)

namespace frozenca {

using namespace std;

template <ranges::input_range R>
void print(R&& r, ostream& os = cout) {
    for (auto elem : r) {
        os << elem << ' ';
    }
    os << '\n';
}

mt19937 gen(random_device{}());

template <typename F, ranges::forward_range R = vector<int>> requires regular_invocable<F, R>
void verify_sorting(F&& f, int num_trials = 1'000, int max_length = 1'000) {
    uniform_int_distribution<> len_dist(0, max_length);

    for (int i = 0; i < num_trials; ++i) {
        R v;
        int n = len_dist(gen);
        generate_n(back_inserter(v), n, ref(gen));
        f(v);
        if (!ranges::is_sorted(v)) {
            throw runtime_error("Sorting verification failed");
        }
    }
    std::cout << "Sorting verification success!\n";

}

} // namespace frozenca

и я написал код сортировки вставками следующим образом:

namespace frozenca {

using namespace std;

struct insertion_sort_func {
    template <ranges::bidirectional_range R = vector<int>, typename F = ranges::greater>
    constexpr void operator()(R&& r, F comp = {}) const {
        if (ranges::empty(r)) return;
        for (auto i = next(begin(r)); i != end(r); ++i) {
            auto key = *i;
            auto j = i;
            while (j != begin(r) && comp(*prev(j), key)) {
                iter_swap(prev(j), j);
                --j;
            }
            *j = key;
        }
    }
};

inline constexpr insertion_sort_func insertion_sort{};

} // namespace frozenca

И вот мой тестовый код, который отлично работает:


int main() {
    namespace fc = frozenca;

    std::vector<int> v{5, 2, 4, 6, 1, 3};
    fc::insertion_sort(v);
    fc::print(v); // outputs "1 2 3 4 5 6"
    fc::verify_sorting(std::ranges::sort); // outputs "Sorting verification success!"
    fc::verify_sorting(fc::insertion_sort); // outputs "Sorting verification success!"

}

Моя функция verify_sorting по умолчанию проверяет функцию сортировки для типа std::vector<int>. Конечно, он может протестировать другие std::ranges::forward_range, но становится очень многословным. Для тестирования std::vector<float> то, что я проверил, работает так:

fc::verify_sorting<decltype(fc::insertion_sort), std::vector<float>>
(std::forward<decltype(fc::insertion_sort)>(fc::insertion_sort));
// OK

Это слишком многословно. Есть ли менее подробный способ?

Рабочий код: https://wandbox.org/permlink/4UPLxeJxDlOkXcN1

Этот вопрос, вероятно, относится к обзору кода. Кроме того, using namespace std допустимо, когда оно заключено в контролируемую область. Когда вы видите его в глобальном пространстве имен, это может вызвать проблемы.

Constantinos Glynos 10.04.2022 08:13

@ConstantinosGlynos: Вы, вероятно, не хотите, чтобы frozenca::cout «работал» где-то еще в программе.

Davis Herring 10.04.2022 09:36

@DavisHerring В моем коде используется пространство имен std; действителен только в блоке пространства имен Frozenca { }

frozenca 10.04.2022 09:44

Показанный код находится внутри заголовка (поскольку он определяет шаблоны)?

Sebastian 10.04.2022 09:46

@Sebastian Код находится внутри заголовка, но включение его из другого файла неявно не объявляет использование пространства имен std; в этом файле, вы можете попробовать. Если я перемещаюсь, используя пространство имен std; за пределами блока namespace { } , тогда, конечно, это большая проблема

frozenca 10.04.2022 09:50

@frozenca: он по-прежнему позволяет членам std быть доступ к через этому пространству имен в другом месте (надеюсь, эта ссылка будет работать, когда Wandbox будет исправлен).

Davis Herring 10.04.2022 18:53
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
6
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

This is way too verbose. Is there any less verbose way?

Просто измените порядок параметров шаблона

template <ranges::forward_range R = vector<int>, typename F> 
  requires regular_invocable<F, R>
void verify_sorting(F&& f,  /* */);

Затем вы можете просто вызывать вот так

fc::verify_sorting(std::ranges::sort);
fc::verify_sorting(fc::insertion_sort);
fc::verify_sorting<std::vector<float>>(fc::insertion_sort);

Демо

Другие вопросы по теме