#define FALSE 0
#define TRUE 1
#define IDS_MYSTR 123
void FnVariadic(const long nIDS, ...)
{
std::cout << "WITHOUT option IDS" << std::endl;
}
void FnVariadic(const bool bOption, const long nIDS, ...)
{
std::cout << "WITH option IDS" << std::endl;
}
void FnVariadic(const char *pStr, ...)
{
std::cout << "WITHOUT option STR" << std::endl;
}
void FnVariadic(const bool bOption, const char *pStr, ...)
{
std::cout << "WITH option STR" << std::endl;
}
int main()
{
FnVariadic(FALSE, IDS_MYSTR, "abc");
//FnVariadic(IDS_MYSTR, FALSE, "abc"); //???
FnVariadic(TRUE, IDS_MYSTR, "abc");
FnVariadic(IDS_MYSTR, TRUE, "abc"); //???
FnVariadic(FALSE, "abc%s", "abc");
//FnVariadic("abc%d%s", FALSE, "abc");
FnVariadic(TRUE, "abc%s", "abc");
//FnVariadic("abc%d%s", TRUE, "abc");
system("pause");
return 0;
}
谁能解释一下这里的功能重载解决是如何工作的? 令人惊讶的事情就在那里;
//FnVariadic(IDS_MYSTR, FALSE, "abc"); //???
FnVariadic(IDS_MYSTR, TRUE, "abc"); //???
第二个编译但不是第一个。
(注释行表示不编译。)
我用的是VS2017,好像是;
前 3 次调用使用 void FnVariadic(const bool bOption, const long nIDS, ...)
,最后 2 次调用使用 void FnVariadic(const bool bOption, const char *pStr, . ..)
那里也很有趣。我期望的是应该调用没有 bool 参数的重载。
最佳答案
省略号是重载决议的最后手段,如果有更好的匹配,那么函数调用将被解析为那个匹配。您的函数调用(未注释)都涉及一个整数文字作为第一个参数。由于您的宏在被替换时都是转换为 bool
的可行候选者,因此您有两个候选者
void FnVariadic(const bool bOption, const long nIDS, ...)
void FnVariadic(const bool bOption, const char *pStr, ...)
然后在前三个中,您提供整数文字作为第二个参数。所以调用上面两者之间的第一个重载。在最后 2 个中,您提供了字符串文字(可衰减为 const char*
),因此在上述两个重载之间调用了第二个重载。
至于为什么注释行不编译
// FnVariadic(IDS_MYSTR, FALSE, "abc"); //???
这不会编译,因为第二个参数不明确,0
不幸的是有特殊含义,它既可以解析为 const char*
也可以解析为 常量长
// FnVariadic("abc%d%s", FALSE, "abc");
这个也一样,FALSE
是不明确的
// FnVariadic("abc%d%s", TRUE, "abc");
此处将"abc%d%s"
转换为bool
和将"abc"
匹配到省略号是一样的优先级,因此它是模棱两可的。
供您引用,使用编译时可变参数模板几乎总是优于 C 样式可变参数。
关于c++ - 工作函数重载如何使用可变参数进行解析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44969183/