Fungsi menerima fungsi sebagai parameter dengan tipe templated

Dec 18 2020

im cukup baru untuk pemrograman dan C ++. Saya memiliki fungsi yang ingin saya terima function-pointers dengan nilai templated sebagai argumen. Inilah yang saya maksud ...

saya memiliki fungsi ini:

template<typename... ColumnTypes, typename... ParameterTypes>
   void query(std::function<void(bool success, ozo::rows_of<ColumnTypes...>& results)> callback, const 
   std::string& query, ParameterTypes&& ... parameters);

"ozo :: row_of" adalah alias untuk:

template <typename ... Ts>
   std::vector<std::tuple<Ts...>> 

Saya ingin setiap kueri dilengkapi dengan panggilan balik, panggilan balik ini harus dapat menerima jenis yang berbeda. misalnya. "ColumnTypes"

Apa yang saya coba:

void myfunc(bool succeeded, ozo::rows_of<int>& results)
{
     //code
}

postgres_caller->query(myfunc, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);

hasil:

.cpp:241:26: error: no matching member function for call to 'query'
    postgres_caller->query(myfunc, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);
    ~~~~~~~~~~~~~~~~~^~~~~

.h: 165: 22: catatan: template kandidat diabaikan: tidak dapat cocok dengan 'fungsi <void (bool, vektor <tuple <type-parameter-0-0 ...>, pengalokasi <tuple <type-parameter-0-0 ...>>> &)> 'melawan' void (*) (bool, std :: vectorstd :: tuple <int, std :: alokatorstd :: tuple <int>> &) 'void PostgresCaller :: query (std :: function <void (bool success, ozo :: row_of <ColumnTypes ...> & results)> callback, const std :: string & query, ParameterTypes && ... parameter)

Saya juga mencoba lambda:

postgres_caller->query([](bool succeeded, ozo::rows_of<int>& results)
                            {
                                //code
                            }, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);

hasil:

error: no matching member function for call to 'query'
    postgres_caller->query([](bool succeeded, ozo::rows_of<int>& results)
    ~~~~~~~~~~~~~~~~~^~~~~

.h: 165: 22: catatan: template kandidat diabaikan: tidak dapat cocok dengan 'fungsi <void (bool, vektor <tuple <type-parameter-0-0 ...>, pengalokasi <tuple <type-parameter-0-0 ...>>> &)> 'melawan' (lambda di .cpp: 241: 32) 'void PostgresCaller :: query (std :: function <void (sukses bool, ozo :: row_of <ColumnTypes ...> & hasil)> callback, const std :: string & query, ParameterTypes && ... parameter) ^

Apakah ini bisa dilakukan dan bagaimana melakukannya? sangat dihargai. / John

Jawaban

1 super Dec 18 2020 at 23:02

Pemotongan template hanya berfungsi pada jenis yang tepat yang Anda berikan, jadi jika Anda meneruskan penunjuk fungsi, template tidak dapat menyimpulkan jenis std::functionuntuk mengonversi penunjuk fungsi tersebut.

Jadikan callable sebagai parameter template, alih-alih menggunakan std::function.

template<typename Callable, typename... ParameterTypes>
void query(Callable callback, const std::string& query, ParameterTypes&& ... parameters) {
    callback( ... ); // use it like this
}

Seringkali Anda tidak perlu menyimpulkan tanda tangan panggilan balik. Sebut saja dengan argumen yang Anda harapkan.

Jika ini tidak cukup, ada beberapa cara untuk menyimpulkan tanda tangan dari callback juga, tetapi itu menjadi sedikit lebih bertele-tele dan sebagian besar waktu tidak memiliki tujuan yang sebenarnya.