c++ - 工作函数重载如何使用可变参数进行解析?

标签 c++ overloading variadic-functions

#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/

相关文章:

c++ - 使用 C++ lambda 正确实现 finally block

c++ - 使用智能指针建模所有权的含义

c++ - vector<int*>.push_back() 正在覆盖 front() 指向的值

c - 如何判断一个可选参数是否传递给函数 C

c++ - 没有命名参数的变量参数列表?

带 header 的 C++ 委托(delegate)构造函数

Python:子类可以重载继承的方法吗?

c++ - 重载有理数类的 istream >> 运算符。不知道如何处理整数

c++ - GCC C++14/17 成员函数指针模板参数的区别

variadic-functions - 如何证明这个关于 eta 展开的引理?