generic function name jako parametr

0

cześć
patrzę sobie po internetach (ucząć się cpp)

i na tej podstawie napisalem (raczej przepisałem ze zrozumieniem) takie coś jak poniżej

i teraz mi chodzi jak przekazać nazwę metody generycznej tak aby konkretyzacja była "automatyczna" gdzieś juz w metodzie test_impl


#include <functional>
#include <iostream>
#include <string>
#include <tuple>
#include <iostream>
#include <tuple>
#include <functional>

int add(int first, int second)
{
	return first + second;
}

template<typename T>
void print(T first, T second)
{
	std::cout << first << " " << second<<"\n";
}

template <class TCallable, typename TTuple, size_t... index>
constexpr decltype(auto) test_impl(TCallable &&callable, TTuple &&tuple, std::index_sequence<index...>)
{
	return std::invoke(std::forward<TCallable>(callable), std::get<index>(std::forward<TTuple>(tuple))...);
}

template <class TCallable, typename TTuple>
constexpr decltype(auto) test(TCallable &callable, TTuple &tuple)
{
	return test_impl(std::forward<TCallable>(callable), std::forward<TTuple>(tuple), std::make_index_sequence<std::tuple_size_v<TTuple>> {});
}

int main()
{
	auto tuple =std::make_tuple(1, 2) ;

        //co zrobić aby to było poprawne
	test(print, tuple);

	return 0;
}
0

Nie działa bo szablon funkcji to nie to samo co funkcja. Zamiast szablonu napisz po po prostu

void print(int first, int second)
{
    std::cout << first << " " << second<<"\n";
}

I będzie działać. W uproszczeniu, print dla kompilatora nie istnieje jeśli nie doprecyzujesz go typem w którymś miejscu w kodzie. Dlatego też, kompilator nie może wydedukować sobie typów dla test bo nie ma z czego dedukować.

Ewentualnie, jeśli chcesz zachować print jako szablon, zrób coś takiego

test(print<int>, tuple);

I też będzie działać. W każdym razie, gdzieś w końcu musisz podać konkretny typ, kompilator nie ma kryształowej kuli i nie wyczaruje Ci go z nikąd ;)

0

AFAIK się nie da. Ale możesz opakować to w lambdę:

int main()
{
    auto tuple =std::make_tuple(1, 2) ;

        //co zrobić aby to było poprawne
    test([](auto&&... params){ return print(std::forward<decltype(params)>(params)...); }, tuple);

    return 0;
}

Po poprawieniu test (lvalue ref ⟶ forwarding ref, decay na TTuple):

template <class TCallable, typename TTuple>
constexpr decltype(auto) test(TCallable&& callable, TTuple&& tuple)
{
    constexpr auto size = std::tuple_size<std::decay_t<TTuple>>::value;
    return test_impl(std::forward<TCallable>(callable), std::forward<TTuple>(tuple), std::make_index_sequence<size> {});
}

Wydaje się działać: https://wandbox.org/permlink/VcW6t4XdCntVF6vG

1 użytkowników online, w tym zalogowanych: 0, gości: 1