C++ 如何在C++;
假设我想让一个函数重载两个版本,如下所示: a)C++ 如何在C++;,c++,overloading,variadic-functions,C++,Overloading,Variadic Functions,假设我想让一个函数重载两个版本,如下所示: a) void查询(常量字符串&s)对服务器进行SQL查询 b) void查询(常量字符串&s,…),它构建由格式字符串和要替换的参数给出的查询字符串。在内部,这个版本看起来像(我隐藏细节以避免问题过于复杂): 请注意,我还希望它在MSVC和GCC中都能工作。当然,通过如上所述的写作,由于模棱两可,我不能接受以下要求: 查询(“…”) 为了解决这种情况下的歧义,我尝试了几种方法,但没有一种有效: 1)将它们重写为: void query(const s
void查询(常量字符串&s)代码>对服务器进行SQL查询
b) void查询(常量字符串&s,…)代码>,它构建由格式字符串和要替换的参数给出的查询字符串。在内部,这个版本看起来像(我隐藏细节以避免问题过于复杂):
请注意,我还希望它在MSVC和GCC中都能工作。当然,通过如上所述的写作,由于模棱两可,我不能接受以下要求:
查询(“…”)代码>
为了解决这种情况下的歧义,我尝试了几种方法,但没有一种有效:
1)将它们重写为:
void query(const string& s) {
// ...
}
template<typename Value>
void query(const string& s, Value value,...) {
va_list vargs;
va_start(vargs, s);
// ...
}
同样,它编译并使用MSVC。但是GCC抱怨第二个版本是可变模板而不是可变函数,并且不允许在那里使用va_start
。GCC中的va_start
似乎是内置的,而不是来自库
有些人可能会说,实际上在这两个版本中,第二个版本取代了第一个版本。这意味着,如果我删除第一个版本并将其内部放入第二个版本,那么一切都正常。但是我有一个很好的理由保留第1个版本:我希望只使用一个字符串直接调用,而不必不必要地调用vsnprintf
。所以请不要这样建议我
我还考虑过将第一个版本合并到第二个版本中,然后在内部计算给定参数的数量,以了解如何进行。但它似乎没有一个标准的方法来做到这一点。可以使用可变模板确定参数的数量,但不能使用可变函数。如果我切换到可变模板,我就不能再在GCC中使用va_start
希望有人能帮忙 我还没有测试过这一点,但是下面的测试是否有效
void query_varargs(const string &s, ...) {
va_list vargs;
va_start(vargs, s);
// ...
}
template<typename... Values>
enable_if<(sizeof...(Values) > 0), void>::type
query(const string& s, Values value...) {
query_varargs(s, ...value);
}
void查询\u varargs(常量字符串和字符串,…){
va_列表变量;
va_启动(vargs,s);
// ...
}
模板
启用(如果为0),void>::键入
查询(常量字符串和字符串、值…){
查询变量(s,…值);
}
也就是说,将功能移到另一个功能中(query\u varargs
),然后将变量模板版本的query
转发给它。为什么让它们重载?为什么不给他们起不同的名字呢?它们似乎做了非常不同的事情。“我希望只使用一个字符串直接调用,而不必不必要地调用vsnprintf
”——您对此进行了基准测试吗?这会给你带来多少性能?@Carcigenicate:只是为了简化透明的使用。非常感谢,你救了我的命!实际上,这是这个库的一部分:现在它工作得非常完美。
void query(const string& s) {
// ...
}
template<typename... Values>
enable_if<(sizeof...(Values) > 0), void>::type
query(const string& s, Values value...) {
va_list vargs;
va_start(vargs, s);
// ...
}
void query_varargs(const string &s, ...) {
va_list vargs;
va_start(vargs, s);
// ...
}
template<typename... Values>
enable_if<(sizeof...(Values) > 0), void>::type
query(const string& s, Values value...) {
query_varargs(s, ...value);
}