简体   繁体   English

C ++ 20-模板参数推导/替换问题

[英]C++20 - Template argument deduction/substitution problem

I am tring to write the function sql_exec to run a serializable transaction in a Postgresql database using pqxx and I still fail, because of Template argument deduction/substitution problem. 我正在尝试编写函数sql_exec以使用pqxx在Postgresql数据库中运行可序列化事务,但是由于Template参数推导/替换问题,我仍然失败。

I have tried to rewrite template function many times, but I don't really know, what is wrong and don't understand, why the compiler returns error. 我已经尝试了很多次重写模板函数,但是我真的不知道什么是错误的,也不知道是什么,为什么编译器会返回错误。

This is the function 这是功能

namespace kp{
  pqxx::connection get_conn();
  int txn_rep();

  using txn_rlbck = pqxx::transaction_rollback;
  using t_txn = pqxx::transaction<pqxx::serializable>; 
  using t_con = pqxx::connection;

  class txn_gen{
    t_con& con;
    int enu = 0;

  public:
    txn_gen(t_con& con) : con(con){};

    void except(const txn_rlbck& ex);
    t_txn txn();
  };

  template<typename t_function, typename... t_args>
    std::invoke_result_t<std::decay_t<t_function>, std::decay_t<t_txn&>, std::decay_t<t_args>...> sql_exec(t_con& conn, t_function&& f, t_args&&... args){
      txn_gen gen(conn);
      while(true){
        try{
          auto&& txn = gen.txn();
          auto&& ret = f(txn, args...);
          txn.commit();

          return ret;
        }
        catch(txn_rlbck& ex){
          gen.except(ex);
        }
      }
    }

};

Then I used it in this lambda 然后我在这个lambda中使用了它

 auto map_deamon = [this]{
    while(true){
      std::this_thread::sleep_for(to_duration(settings.update_map_period));

      t_con conn = get_conn();
      std::unique_lock<std::mutex> lock(map_overload_mutex);

      auto&& reload = [this, &lock](t_txn& txn){
        mp::tt_map new_map = obtain_map(txn, settings, walk_machine, car_machine);

        lock.lock();
        map = std::make_shared<mp::tt_map> (std::move(new_map));
      };

      sql_exec(conn, reload);
    }
  };

And compiler returned this error 然后编译器返回此错误

src/path_planner.cpp: In lambda function:
src/path_planner.cpp:61:32: error: no matching function for call to ‘sql_exec(kp::t_con&, kp::server_instance::boot()::<lambda()>::<lambda(kp::t_txn&)>&)’
           sql_exec(conn, reload);
                                ^
In file included from src/path_planner.cpp:12:
include/sql.hpp:27:99: note: candidate: ‘template<class t_function, class ... t_args> std::invoke_result_t<typename std::decay<_Tp>::type, pqxx::transaction<(pqxx::isolation_level)2, (pqxx::readwrite_policy)1>, std::decay_t<t_args>...> kp::sql_exec(kp::t_con&, t_function&&, t_args&& ...)’
     std::invoke_result_t<std::decay_t<t_function>, std::decay_t<t_txn&>, std::decay_t<t_args>...> sql_exec(t_con& conn, t_function&& f, t_args&&... args){
                                                                                                   ^~~~~~~~
include/sql.hpp:27:99: note:   template argument deduction/substitution failed:
src/path_planner.cpp: In function ‘void kp::boot()’:

Can you suggest me, where the problem is please? 你能建议我,问题出在哪里?

Thank you. 谢谢。

Your method is SFINAEd, as reload(std::declval<t_txn>()) is invalid ( reload(std::declval<t_txn&>()) would be valid) 您的方法为SFINAEd,因为reload(std::declval<t_txn>())无效( reload(std::declval<t_txn&>())将有效)

You might use decltype(auto) 您可以使用decltype(auto)

template<typename t_function, typename... t_args>
decltype(auto)
sql_exec(t_con& conn, t_function&& f, t_args&&... args)

or get rid of std::decay (especially for t_txn& ): 或摆脱std::decay (尤其是对于t_txn& ):

template<typename t_function, typename... t_args>
std::invoke_result_t<t_function, t_txn&, t_args...>
sql_exec(t_con& conn, t_function&& f, t_args&&... args)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM