przekazywanie funkcji do funkcji przez referencję

przekazywanie funkcji do funkcji przez referencję
Mc_Hammer
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
0

Witam

w jaki sposób określić, że funkcja - przekazywana przez referencję do innej funkcji - powinna zwracać jakiś typ, np. bool ?

Kopiuj
    template<typename Func>
    void matrix_loop(const Func &f)
    {
        for(uint8_t row = 0; row < MATRIX_ROWS; ++row)
        {
            for(uint8_t col = 0; col < MATRIX_COLS; ++col)
            {
                if(f(row, col))
                    return;
            }
        }
    }

powyższy kod oczywiście nie działa i kompilator krzyczy: value of type 'void' is not contextually convertible to 'bool'

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Nie ma potrzeby wykorzystywania szablonów - wklep c++ function pointers w Google, a znajdziesz kilka rozwiązań :-)


edytowany 1x, ostatnio: Patryk27
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:43 minuty
  • Postów:4928
0

Możesz użyć funktorów (function object).


MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:9 minut
5
Patryk27 napisał(a):

Nie ma potrzeby wykorzystywania szablonów - wklep c++ function pointers w Google, a znajdziesz kilka rozwiązań :-)

Wskaźniki na funkcje to jest przeżytek w C++ i spadek po C. Lepiej ich unikać.

A co do tematu, wersja łatwa bez szablonów (ale wolniejsze od wskaźników):

Kopiuj
void matrix_loop(std::function(bool(int,int)))
{

Zlalety łatwe przyjemne może być częścią API dll.

Wersja szablonowa, szybsza nawet od wskaźników (byłeś blisko):

Kopiuj
    template<typename Func>
    void matrix_loop(Func &&f) // perfect forwarding
    {

Normalnie olewa się to, że tam ma być coś innego i w razie problemów czyta okropne błędy szablonów.
W C++20 będą koncepty, gdzie wyraźnie można określić wymagania co do typu Func

W C++11 da się jednak coś temu zaradzić korzystając ze SFINAE:

Kopiuj
    template<typename Func>
    std::enable_if<std::is_same<std::result_of<Func(int, int)>::type, bool>::value>::type
    matrix_loop(Func &&f) // perfect forwarding
    {

Dla porządku wersja ze wskaźnikiem:

Kopiuj
void matrix_loop(bool (*f)(int,int))
{

Jest jeszcze możliwość użycia static_assert (jako namiastka konceptów):

Kopiuj
    template<typename Func>
    void matrix_loop(Func &&f) // perfect forwarding
    {
        static_assert(std::is_same<std::result_of<Func(int, int)>::type, bool>::value, "Func must return 'bool' type");

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22
Mc_Hammer
Dzięki, wykorzystam to rozwiązanie ze static_assert

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.