簡體   English   中英

工作函數如何使用可變參數解析?

[英]How does work function overload resolving with variadic arguments?

#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可行候選者時,你有兩個候選者

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");

這里,對於"abc%d%s" bool的轉換和"abc"與省略號的匹配具有相同的優先級,因此它是不明確的。


作為參考,使用編譯時可變參數模板而不是C樣式可變參數幾乎總是更好。

正如@Shaggi已經指出的那樣。 符合標准,

在引入nullptr之前,將零(0)用作空指針的表示法。 例如:

 int* x = 0; // x gets the value nullptr 

沒有為地址0分配對象,0(全零位模式)是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, ...)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM