テンプレート化されたタイプのパラメーターとして関数を受け入れる関数

Dec 18 2020

プログラミングとC ++はかなり新しいです。テンプレート化された値を引数として持つ関数ポインターを受け入れたい関数があります。これが私が意味することです...

私はこの機能を持っています:

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 :: rows_of」は次のエイリアスです:

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

各クエリにコールバックを提供したいのですが、このコールバックはさまざまなタイプを受け入れることができる必要があります。例えば。「ColumnTypes」

私が試したこと:

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);

結果:

.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:注:候補テンプレートは無視されました:一致しませんでした 'function <void(bool、vector <tuple <type-parameter-0-0 ...>、allocator <tuple <type-parameter-0-0 ... >>>&)> 'に対して' void(*)(bool、std :: vectorstd :: tuple <int、std :: allocatorstd :: tuple <int >>&) 'void PostgresCaller :: query(std :: function <void(bool success、ozo :: rows_of <ColumnTypes ...>&results)>コールバック、const std :: string&query、ParameterTypes && ... parameters)

私もラムダで試しました:

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

結果:

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

.h:165:22:注:候補テンプレートは無視されました:一致しませんでした 'function <void(bool、vector <tuple <type-parameter-0-0 ...>、allocator <tuple <type-parameter-0-0 ... >>>&)> 'に対して'(lambda at .cpp:241:32) 'void PostgresCaller :: query(std :: function <void(bool success、ozo :: rows_of <ColumnTypes ...>&結果)>コールバック、const std :: string&query、ParameterTypes && ...パラメータ)^

これは実行可能であり、どのように実行できますか?とても有難い。/ジョン

回答

1 super Dec 18 2020 at 23:02

テンプレートの推定は、渡した正確な型でのみ機能するため、関数ポインターを渡した場合、テンプレートはstd::functionその関数ポインターを変換する種類を推定できません。

を使用する代わりに、呼び出し可能ファイルをテンプレートパラメータにしstd::functionます。

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

ほとんどの場合、コールバックの署名を推測する必要はありません。あなたがそれが取ると期待する引数でそれを呼ぶだけです。

これだけでは不十分な場合は、コールバックのシグネチャを推測する方法もありますが、もう少し冗長になり、ほとんどの場合、実際の目的はありません。