#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, ...)
那里也很有意思。我所期望的是应该调用没有布尔参数的重载。
答案 0 :(得分:2)
省略号是重载分辨率的最后手段,如果有更好的匹配,则函数调用将被解析为该匹配。您的函数调用(未注释)都涉及整数文字作为第一个参数。而且,由于您的宏在更换时都是转换为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*
以及const long
// FnVariadic("abc%d%s", FALSE, "abc");
对于这一个,FALSE
是不明确的
// FnVariadic("abc%d%s", TRUE, "abc");
此处bool
与"abc%d%s"
的转换以及"abc"
与省略号的匹配具有相同的优先级,因此不明确。
供您参考,使用编译时可变参数模板而不是C样式可变参数几乎总是更好。
答案 1 :(得分:1)
正如@Shaggi已经指出的那样。符合标准,
在引入nullptr之前,使用零(0)作为符号 空指针。例如:
int* x = 0; // x gets the value nullptr
没有为对象分配地址0和0(全零位 pattern)是nullptr的最常见表示。零(0)是一个 INT。但是,标准转换(第10.5.2.3节)允许使用0 作为指针或指向成员类型的常量
FnVariadic(IDS_MYSTR, FALSE, "abc");
^~~~const char * OR const long. This is ambiguous.
因为你有两个
void FnVariadic(const bool bOption, const long nIDS, ...)
void FnVariadic(const bool bOption, const char *pStr, ...)