调用std::get处理const tuple引用时无匹配函数的编译问题求助
解决你的std::get编译错误及相关问题
嘿,我来帮你搞定这个编译问题,根源是std::get的模板参数用错了,还有几个递归和索引的小细节需要调整,咱们一步步来:
1. 先修复std::get的调用
你现在写的:
std::get<I, std::tuple<T...> > (values);
完全没必要显式指定tuple类型——编译器能自动从values推导出来,而且这种写法反而导致匹配不到正确的std::get重载。直接改成:
std::get<I>(values);
这就解决了核心的编译错误。
2. 修正递归终止的特化逻辑
你对Visit_Tup_Impl<0>的特化针对的是空tuple,这和递归逻辑不搭——当递归到I=0时,咱们的tuple肯定是有元素的啊。正确的特化应该处理任意非空tuple的0索引情况:
template<> template<typename... T> const std::string& Visit_Tup_Impl<0>::visit_tup(const std::tuple<T...>& values, int comp) { if (0 == comp) { // 这里换成你实际的转换逻辑,比如调用to_sql_string return to_sql_string(std::get<0>(values)); } else { assert(false && "comp值超出tuple的索引范围"); return EMPTY_STRING; } }
另外记得要定义EMPTY_STRING为全局的空字符串实例:
const std::string EMPTY_STRING = "";
3. 修复索引不匹配的bug
在create_coupled_query里,你从i=1开始循环,但tuple的索引是从0开始的,这会导致永远访问不到tuple的第一个元素,甚至可能越界。得把循环起始值改成0,同时把传递给visit_tup的comp参数改成i(因为现在i从0开始了):
template <typename ...T> std::string create_coupled_query (const std::vector<std::string>& keys, const std::vector<std::tuple<T...> >& values) { // 先加个断言,确保keys的数量和tuple元素数一致,避免后续出错 assert(keys.size() == sizeof...(T) && "keys的数量和tuple元素数量不匹配"); std::ostringstream local; local << "("; auto iter = values.begin(); const auto iter_end = values.end(); for (; iter != iter_end; ++iter) { local << "("; std::size_t i = 0; for (; i < keys.size(); ++i) { local << keys[i] << "=" << to_sql_string(Visit_Tup_Impl<sizeof...(T)-1>::visit_tup(*iter, i)); if (i != keys.size() - 1) { local << " AND "; } } local << ")"; if (std::next(iter) != iter_end) { local << " OR "; } } local << ")"; return local.str(); }
4. 别忘了实现to_sql_string的重载
你得确保to_sql_string能处理tuple里的所有类型,比如ACE_Time_Value和std::string:
std::string to_sql_string(const ACE_Time_Value& tv) { // 这里写时间转SQL字符串的逻辑,比如转成带引号的时间格式 return "'" + std::to_string(tv.sec()) + "." + std::to_string(tv.usec()) + "'"; } std::string to_sql_string(const std::string& s) { // 处理字符串的单引号转义,避免SQL注入 std::string escaped = s; std::replace(escaped.begin(), escaped.end(), '\'', '\''); return "'" + escaped + "'"; }
做完这些修改后,你的代码应该就能正常编译运行,生成你想要的多组OR条件的SQL查询语句了。
内容的提问来源于stack exchange,提问作者Guy Ti
相关产品推荐
相关产品推荐

