Аргумент шаблона не совпадает в функции вызова переменной кортежа - PullRequest
1 голос
/ 09 мая 2019

Почему компилятор не может соответствовать параметру шаблона F в функции invoke(). Есть ли где-нибудь невнедренный контекст, о котором я не знаю ?? И как это можно исправить?

Живите

// Invoke Function with all tuple arguments.
template<typename F, size_t... Is, typename Tuple>
auto invoke(F&& f, std::index_sequence<Is...>, Tuple&& t)
{
    return f(std::get<Is>(t)...);
}

template<typename F, typename Tuple>
auto invoke(F&& f, Tuple&& t)
{
    constexpr std::size_t uiLength = std::tuple_size_v<std::remove_reference_t<Tuple>>;
    return invoke(std::forward<F>(f),
                  std::make_index_sequence<uiLength>{},
                  std::forward<Tuple>(t));
}

template<typename T>
struct A{
   using D = int;
};
template<typename... T>
auto make(T&...){
    return std::make_tuple(A<T>{}...);
}

int main()
{
  invoke([](auto&, auto&){}, std::make_tuple(A<int>{}, A<double>{})); // works
  //auto a = invoke(make, std::make_tuple(A<int>{}, A<double>{})); // does not compile, but why??
}

Ответы [ 2 ]

2 голосов
/ 09 мая 2019

Есть ли где-нибудь невысказанный контекст, о котором я не знаю ??И как это можно исправить?

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

template<typename... T>
auto make(T&...){
    return std::make_tuple(A<T>{}...);
}

// ...

auto a = invoke(make, std::make_tuple(A<int>{}, A<double>{}));

Попробуйте переписать make() как универсальную (и вариационную) лямбду (то есть объект, чтобы вы могли передать ее в качестве аргумента функции)

auto a = invoke([](auto & ... rData){ return std::make_tuple(A<decltype(rData)>{}...);},
                std::make_tuple(A<int>{}, A<double>{}));

Выкл. Тема: переименуйте invoke() с другимname (myInvoke(), в качестве примера), чтобы уменьшить риск конфликта имен с std::invoke().

0 голосов
/ 10 мая 2019

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

static const auto makeDataHandles = [](auto&... t) {
    return std::make_tuple(A<std::remove_reference_t<decltype(t)>>{}...);
}
...