Передача определенной функции в шаблон - PullRequest
1 голос
/ 10 апреля 2019

Я пытаюсь передать функцию в шаблон, и до сих пор я получил это:

template <typename T, typename U> void special_sort(std::vector<T>& container, std::vector<U>& ordering_container,
    std::function<std::vector<std::pair<unsigned int, unsigned int>>(std::vector<U>&)>& sort_function) {

    sort_function(ordering_container);
}

В основном я объявил это:

std::vector<std::pair<unsigned, unsigned>> sort_function(std::vector<int>&) {
    std::vector<std::pair<unsigned int, unsigned int>> a;
    return a;
}

int main() {
    std::vector<std::string> test_container = {"a", "b", "c"};
    std::vector<int> test_ordering_container = {4,7,2};

    auto a = sort_function(test_ordering_container);
    special_sort<std::string, int>(test_container, test_ordering_container, sort_function(test_ordering_container));
}

Но яполучаю следующую ошибку:

Ошибка (активная) E0304 нет экземпляра шаблона функции "special_sort", совпадающего со списком аргументов Objective_challenge C: \ Users \ mdp11 \ source \ repos \ Objective_challenge \ Objective_challenge \ main.cpp 21 тип аргумента: (std::vector<std::string, std::allocator<std::string>>, std::vector<int, std::allocator<int>>, std::vector<std::pair<unsigned int, unsigned int>, std::allocator<std::pair<unsigned int, unsigned int>>>)

Что я делаю неправильно?Спасибо всем заранее.

Ответы [ 2 ]

2 голосов
/ 10 апреля 2019

Итак, у вас здесь две ошибки.

Во-первых, это:

special_sort<std::string, int>(
    test_container, test_ordering_container, 
    sort_function(test_ordering_container)
);//     --------^-----------------------^

Вместо отправки функции вы вызываете ее и отправляете результат.

Компилятор жалуется на вектор, не преобразуемый в std::function.

special_sort<std::string, int>(
    test_container, test_ordering_container, 
    sort_function
);//        ^------ the function itself

Вторая ошибка - получение функции по изменяемой ссылке.

Тип функции , а не std::function. Тип sort_function является типом указателя на функцию.

Класс std::function - это полиморфная обертка вокруг любого вызываемого. Таким образом, лямбда-тип, тип объекта-функции, указатель на функцию и тому подобное могут содержаться в std::function стертым способом.

При отправке указателя функции в качестве параметра вашей функции он должен создать временную std::function. Но проблема здесь в том, что временные ссылки не могут быть связаны с изменяемой ссылкой, только константами:

template <typename T, typename U>
void special_sort(
    std::vector<T>& container,
    std::vector<U>& ordering_container,
    std::function<std::vector<std::pair<unsigned int, unsigned int>>(std::vector<U>&)> const& sort_function
) { //                            -----------------------------------------------------^

}

Или вы также можете использовать параметр шаблона. Вам не нужен полиморфизм времени выполнения и стирание типа в этом конкретном случае. Сделайте то, что делает STL, и просто возьмите вызываемое по значению:

template <typename T, typename U, typename F>
void special_sort(
    std::vector<T>& container,
    std::vector<U>& ordering_container,
    F sort_function
) {
    // much simpler
    // you can still do:
    // sort_function(ordering_container)
}
1 голос
/ 10 апреля 2019

Есть две ошибки. Во-первых, используйте это:

special_sort<std::string, int>(test_container, test_ordering_container, sort_function);

вместо

special_sort<std::string, int>(test_container, test_ordering_container, sort_function(test_ordering_container));

Вы передавали результат функции вместо самой функции.

Вам также нужно объявить аргумент special_sort как

const std::function<std::vector<std::pair<unsigned int, unsigned int>>(std::vector<U>&)>& sort_function

вместо

std::function<std::vector<std::pair<unsigned int, unsigned int>>(std::vector<U>&)>& sort_function

Поскольку sort_function относится к вызову стандартной функции, его необходимо преобразовать в std::function, чтобы можно было вызвать special_sort. Однако это неявное преобразование создаст временный объект, который не может быть передан как ссылка. Но ссылка на const принимается для временных объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...