Шаблон функции с постоянной времени выполнения - PullRequest
2 голосов
/ 25 марта 2019

Мне нужен какой-то способ объединить способность лямбды перехватывать значение времени выполнения и способность шаблона функции указывать любой тип, который мы хотим. Каков наилучший способ сделать это?

Лямбда позволяет нам захватывать значение локальной переменной во время выполнения, например,

unsigned char c=0;
auto compareEquality=[c](unsigned char c1) ->bool {return c1==c;};
..
scanner(compareEquality);

Таким образом, scanner передается функция, в которую встроено определенное во время выполнения значение 0, а внутри scanner мы вызываем compareEquality, передавая ей unsigned char для сравнения с 0 или любыми другими значениями, полученными во время выполнения. Но я также хочу, чтобы параметр был любого типа, который я хочу, а не просто unsigned char. Было бы неплохо иметь это:

template<typename T>
bool compareEquality(T data) {
  return ( data== c);//error, what is 'c'?
}

Но с шаблоном функции я не могу встроить постоянную времени выполнения в нее и просто передать функцию следующим образом:

scanner(compareEquality);

Приведенный выше код не позволяет мне указать, какое значение сравнивать внутри функции.

Каков наилучший способ объединить шаблон функции и лямбда-захват, чтобы compareEquality можно было передавать с некоторым встроенным значением времени выполнения, пока нам не нужно определять отдельные версии, принимающие разные типы параметров.

Ответы [ 2 ]

1 голос
/ 25 марта 2019

Что вы можете сделать, так это иметь функцию, которая создает для вас эти лямбды, как показано ниже:

template<typename T>
auto ret_f(const T& p){
    return  [p](const T& p1)-> bool 
               {return p1==p;};
}
struct foo{
    int a;
    double b;
    bool c;

    bool operator==(const foo& f){
        return false;
    }
};

int main() { 
    unsigned char c= 0;
    int i = 0;
    foo bar {22,15.2,false};

    auto fchar = ret_f(c);
    auto fint = ret_f(i);    
    auto f_foo = ret_f(bar);

    cout<<fchar('a');

    cout<<fint(2.6);

    cout<<f_foo(bar);

return 0;

Таким образом, вы можете просто вызвать ret_f с правильным параметром и вернуть правильную лямбду.

1 голос
/ 25 марта 2019

Возможно, я неправильно понял ваш вопрос, но вы могли бы написать функцию более высокого порядка, которая возвращает лямбду:

#include <iostream>
#include <vector>
#include <algorithm>

template <typename T>
constexpr auto is_equal_to(T value)
{
    return [value](T const& x) { return x == value; };   
}

int main(void)
{
    std::vector src {17, 4, 42, 23, 9, 17, 8, 61};   
    int x;
    std::cin >> x;
    std::cout << "count (" << x << "): "
        << std::count_if(src.cbegin(), src.cend(), is_equal_to(x)) << '\n';

    std::cout << "count (42): "
        << std::count_if(src.cbegin(), src.cend(), is_equal_to(42)) << '\n';   
}
...