LINUX.ORG.RU

История изменений

Исправление asaw, (текущая версия) :

Соответственно, параметры он будет сохранять в vector (или что-то подобное) и возникнет проблема: как элементы вектора передавать параметрами в лямбды.

Можно как-то так (C++14):

#include <iostream>
#include <vector>
#include <string>
#include <utility>
#include <functional>

template<typename Vec, std::size_t... I, class... Args>
auto makeHandler(Vec& v, std::index_sequence<I...>, const std::function<void(Args&...)>& fo)
{
    return std::bind(fo, std::ref(v[I])...);
}

template<class... Args>
auto addHandler(std::vector<std::string>& vec, const std::string& /*s*/, const std::function<void(Args&...)>& fo)
{
    return makeHandler(vec, std::index_sequence_for<Args...>{}, fo);
}


int main()
{
    std::vector<std::string> vec {"a1", "a2", "a3", "a4"};
    auto fo = addHandler(vec, "", std::function<void(std::string&)>([](const std::string& s){ std::cout << s << std::endl; }));
    auto fo2 = addHandler(vec, "", std::function<void(std::string&, std::string&)>([](const std::string& s, const std::string& s2){ std::cout << s << ", " << s2 << std::endl; }));
    fo();
    vec[0] = "Hi there!";
    fo();
    fo2();

    return 0;
}
a1
Hi there!
Hi there!, a2

Единственное, от явных кастов вроде std::function<void(std::string&)>() не получается избавиться: лямбда это не std::function и без этого вывод шаблонных типов отказывается работать...

Исправление asaw, :

Соответственно, параметры он будет сохранять в vector (или что-то подобное) и возникнет проблема: как элементы вектора передавать параметрами в лямбды.

Можно как-то так (C++14):

#include <iostream>
#include <vector>
#include <string>
#include <utility>
#include <functional>

template<typename Vec, std::size_t... I, class... Args>
auto makeHandler(Vec& v, std::index_sequence<I...>, const std::function<void(Args&...)>& fo)
{
    return std::bind(fo, std::ref(v[I])...);
}

template<class... Args>
auto addHandler(std::vector<std::string>& vec, const std::string& /*s*/, const std::function<void(Args&...)>& fo)
{
    return makeHandler(vec, std::index_sequence_for<Args...>{}, fo);
}


int main()
{
    std::vector<std::string> vec {"a1", "a2", "a3", "a4"};
    auto fo = addHandler(vec, "", std::function<void(std::string&)>([](const std::string& s){ std::cout << s << std::endl; }));
    auto fo2 = addHandler(vec, "", std::function<void(std::string&, std::string&)>([](const std::string& s, const std::string& s2){ std::cout << s << "," << s2 << std::endl; }));
    fo();
    vec[0] = "Hi there!";
    fo();
    fo2();

    return 0;
}

Единственное, от явных кастов вроде std::function<void(std::string&)>() не получается избавиться: лямбда это не std::function и без этого вывод шаблонных типов отказывается работать...

Исходная версия asaw, :

Можно как-то так (C++14):

#include <iostream>
#include <vector>
#include <string>
#include <utility>
#include <functional>

template<typename Vec, std::size_t... I, class... Args>
auto makeHandler(Vec& v, std::index_sequence<I...>, const std::function<void(Args&...)>& fo)
{
    return std::bind(fo, std::ref(v[I])...);
}

template<class... Args>
auto addHandler(std::vector<std::string>& vec, const std::string& /*s*/, const std::function<void(Args&...)>& fo)
{
    return makeHandler(vec, std::index_sequence_for<Args...>{}, fo);
}


int main()
{
    std::vector<std::string> vec {"a1", "a2", "a3", "a4"};
    auto fo = addHandler(vec, "", std::function<void(std::string&)>([](const std::string& s){ std::cout << s << std::endl; }));
    auto fo2 = addHandler(vec, "", std::function<void(std::string&, std::string&)>([](const std::string& s, const std::string& s2){ std::cout << s << "," << s2 << std::endl; }));
    fo();
    vec[0] = "Hi there!";
    fo();
    fo2();

    return 0;
}

Единственное, от явных кастов вроде std::function<void(std::string&)>() не получается избавиться: лямбда это не std::function и без этого вывод шаблонных типов отказывается работать...