C++ 如何在C++;

C++ 如何在C++;,c++,overloading,variadic-functions,C++,Overloading,Variadic Functions,假设我想让一个函数重载两个版本,如下所示: a) void查询(常量字符串&s)对服务器进行SQL查询 b) void查询(常量字符串&s,…),它构建由格式字符串和要替换的参数给出的查询字符串。在内部,这个版本看起来像(我隐藏细节以避免问题过于复杂): 请注意,我还希望它在MSVC和GCC中都能工作。当然,通过如上所述的写作,由于模棱两可,我不能接受以下要求: 查询(“…”) 为了解决这种情况下的歧义,我尝试了几种方法,但没有一种有效: 1)将它们重写为: void query(const s

假设我想让一个函数重载两个版本,如下所示:

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