Thread overview
C++ Fonksiyon işaretçisi türündeki parametreye std::function türünü geçirmek
Apr 24, 2020
İbrahim
Apr 25, 2020
İbrahim
April 24, 2020

Merhaba;
GLFW kullanıyorum. Bu kütüphanede 'glfwSetKeyCallback' fonksiyonu var ve bu fonksiyonun ikinci parametresi bir fonksiyon işaretçisi alıyor:

typedef void(* GLFWkeyfun) (GLFWwindow *, int, int, int, int)

Ben Modern C++'da olan std::function'ı bu ikinci parametreye geçirmek istiyorum:

void Window::set_keycallback(const std::function<void (GLFWwindow*, int, int, int, int)>& callback)
{
 glfwSetKeyCallback(_window, static_cast<void(*)(GLFWwindow*, int, int, int, int)>(std::bind(callback)));
 // Hatalı kod
}

Fakat tabii ki bu hatalı bir kod. std::function türünü fonksiyon işaretçisine çevirmek mümkün mü?

Teşekkürler.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 24, 2020

Olanaksız çünkü std::function çağrılabilen başka bir şey de olabilir. (Daha genel olan üst sınıfın hangi alt sınıftan oliduğunun bilinememesiyle aynı durum.)

Tam da bu std::function'dan diğerine dönüştüren bir tür yazılabilir ama bu haliyle sorununu çözmüyor çünkü sen bir işlev göstergesi istiyorsun; bu ise bir nesne. Belki bu F nesnesini global bir değişkende saklayıp sonra o değişkeni kullanan bir işlev yazılabilir. Yalnızca bir fikir:

#include <functional>

using FT = std::function<void (int, double)>;

struct F {
 FT f_;

 F(FT f)
   : f_(f)
 {}

 void operator() (int i, double d) {
   return f_(i, d);
 }
};

void foo(int, double) {
}

int main() {
 F f = F(FT(foo));
 f(42, 1.5);
}

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 25, 2020

@acehreli Cevabınız için teşekkürler.
C++ normalde lambda türünü otomatik olarak fonksiyon işaretçisine dönüştürebiliyormuş. Bu sebeple şöyle yaptım:

 template<typename T>
 void set_keycallback(T callback)
 {
   using function_ptr = void (*)(GLFWwindow*, int, int, int, int);
   function_ptr function = callback;
   if (function != nullptr)
     glfwSetKeyCallback(_window, *function);
 }

Fonksiyonu bu şekilde şablon olarak tanımlayınca artık kullanımda argüman olarak hem lambda geçirebiliyorum hem de fonksiyon adresi geçirebiliyorum:

//Lambda:
set_keycallback([](GLFWwindow*, int, int, int, int) {
 // Kodlar
});

void foo(GLFWwindow*, int, int, int, int)
{
 // Kodlar
}

// Fonksiyon Adresi:
set_keycallback(foo);

Tek sıkıntı üye fonksiyonu şablon olarak tanımladığımız için fonksiyon gövdesini başlık dosyasında yazmamız gerekiyor, .cpp dosyasında yazamıyoruz. Bu da gövdelerin kimisinin başlık dosyasında kimisinin .cpp dosyasında olması gibi bir garipliğe sebep oluyor.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]