• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

funkcja przyjmująca dowolną funkcję

VPS Starter Arubacloud
0 głosów
295 wizyt
pytanie zadane 13 stycznia 2018 w C i C++ przez Lebowski Początkujący (330 p.)

Cześć,

Nie potrafię napisać w C++11 funkcji przyjmującej jako argument dowolną funkcję (tzn. o dowolnym typie zwracanym i dowolnej liczbie i typach argumentów).

Próbowałem z szablonami funkcji ale to działa tylko dla ustalonej liczby argumentów:

// definicja:
template<typename Zwrot, typename Arg>
void pomiarCzasuWykonaniaFunkcji(std::function<Zwrot(Arg)> wskDoFunkcji, Arg arg)
{
   //...   ustalenie chwili obecnej tPocz.
   wskDoFunkcji(arg);   // wywolanie danej funkcji.
   //...   ustalenie chwili obecnej tKonc.
   //...   wydruk wartosci: tKonc - tPocz
}


// przykladowe wywolanie:
pomiarCzasuWykonaniaFunkcji<void, int> (foo, 5)   // dla: void foo(int x);

Ale jak to zrobić dla dowolnej liczby argumentów?

M.

1 odpowiedź

0 głosów
odpowiedź 13 stycznia 2018 przez niezalogowany
wybrane 17 stycznia 2018 przez Lebowski
 
Najlepsza

Może tak:

#include <iostream>
#include <chrono>
#include <cmath>

template<class unit = std::chrono::microseconds, class func_t, typename ... args_t>
long long int measure_time(func_t func, const args_t& ... args)
{
	auto start = std::chrono::high_resolution_clock::now();
	func(args ...);
	auto stop = std::chrono::high_resolution_clock::now();
	return std::chrono::duration_cast<unit>(stop - start).count();
}

double func(int a, int b, int c)
{
	return std::pow(std::pow(a, b), c);
}

int main()
{
	std::cout << "Time: " << measure_time(func, 1, 2, 3) << "us \n";
}

Po przecinku możesz wtedy podać dowolną ilość parametrów jakie przyjmuje funkcja.

komentarz 14 stycznia 2018 przez Lebowski Początkujący (330 p.)

Bardzo Tobie dziękuję :)

Przekombinowałem z tym std::function skoro przecież typ funkcji zostanie wydedukowany przez kompilator. A do tego Twój link pomoże mi wreszcie zrozumieć ten ellipsis operator (...). Dziękuję serdecznie.

(Twój nick jest nieco mylący...).

M.

komentarz 14 stycznia 2018 przez mokrowski Mędrzec (155,460 p.)
Brakuje std::forward. Ta funkcja będzie niektóre argumenty "zakłamywała" :-/

Argumenty do docelowej funkcji przekaż przez r-referencję a funkcja docelowa powinna być wywołana z std::forward.
komentarz 16 stycznia 2018 przez Lebowski Początkujący (330 p.)

Czy chodzi Tobie o to, że w ten sposób funkcja mierząca zawsze prześle do funkcji badanej argumenty w postaci l-wartości - nawet wtedy kiedy otrzyma je w postaci r-wartości?

Więc kod mam zmienić na taki?:

#include <iostream>
#include <chrono>
#include <cmath>
 
template<class unit = std::chrono::microseconds, class func_t, typename ... args_t>
long long int measure_time(func_t func, args_t&& ... args)
{
    auto start = std::chrono::high_resolution_clock::now();
    func(std::forward<args_t...>(args ...));
    auto stop = std::chrono::high_resolution_clock::now();
    return std::chrono::duration_cast<unit>(stop - start).count();
}
 
double func(int a, int b, int c)
{
    return std::pow(std::pow(a, b), c);
}
 
int main()
{
    std::cout << "Time: " << measure_time(func, 1, 2, 3) << "us \n";
}

Tylko wtedy nie da się mierzyć funkcji bezargumentowych (bo funkcja std::forward wymaga jednego argumentu.

M.

komentarz 16 stycznia 2018 przez niezalogowany

Raczej tak powinno być:

func(std::forward<args_t>(args) ...);
komentarz 17 stycznia 2018 przez Lebowski Początkujący (330 p.)
Wszystko śmiga! Dzięki.

M.

Podobne pytania

0 głosów
2 odpowiedzi 233 wizyt
pytanie zadane 10 października 2017 w C i C++ przez Pan Kulomb Pasjonat (18,630 p.)
+1 głos
1 odpowiedź 100 wizyt
0 głosów
2 odpowiedzi 92 wizyt
pytanie zadane 17 lutego w Systemy CMS przez pigi98 Nowicjusz (190 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...