匹配bool与const void * overload的函数的地址

时间:2014-12-01 10:47:12

标签: c++ pointers visual-c++ c++11 language-lawyer

我正在阅读Unexpected value using random number generator as a function in C++,评论和当前回答表明用户正在输出该功能的地址。这听起来很合理。我假设发生了函数到指针转换,因此匹配const void*重载,但是在自己测试时,我在GCC / Clang和MSVC中获得了不同的结果。以下测试程序:

#include <iostream>

void test()
{
}

void func(bool)
{
    std::cout << "bool";
}

void func(const void*)
{
    std::cout << "const void*";
}

int main()
{
    func(test);
}

在GCC / Clang中输出bool coliru

MSVC中的

const void* rextester 警告实时协作链接)

N3337说:

[conv.func]

  

函数类型T的左值可以转换为类型的prvalue   &#34;指向T的指针。&#34;结果是指向函数的指针。

[conv.bool]

  

算术,无范围枚举,指针或指针的prvalue   成员类型可以转换为bool类型的prvalue。零   转换value,null指针值或null成员指针值   到false;任何其他值都将转换为true。一个类型的prvalue   std::nullptr_t可以转换为bool类型的prvalue;该   结果值为false

因此,一个不是转换为bool的空指针值的指针应该等于true,这解释了GCC / Clang给出的警告。

然后表12 [over.ics.scs]下的转换给出了一个函数到指针的转换&#34;完全匹配&#34;排名和布尔转换&#34;转换&#34;秩。 [over.ics.rank] / 4然后说:

  

标准转换序列按其等级排序:精确   匹配是比促销更好的转换,这是更好的   转换比转换。两个转换序列相同   除非符合以下规则之一,否则等级无法区分:

     
    

- 不转换指针的转换,指向成员的指针,     或std::nullptr_tbool优于const void*。{/ p>          

- [...]

  

我不是语言律师,所以我希望我引用正确的部分。

然而,即使bool重载不存在,MSVC也会调用bool重载,反之亦然:即使const void*,GCC / Clang也会调用{{1}}重载超载是不存在的。所以我不清楚这里的转换。有人可以为我清楚这一点吗?

1 个答案:

答案 0 :(得分:3)

似乎是MSVC中的错误(或扩展名)。该标准没有定义从“指向函数的指针”到“指向void的指针”的任何标准转换。

很难为缺席提供某些内容的引用,但我能做的最接近的是C ++ 11 4.10 / 2 [conv.ptr]:

  

“指向 cv T指针”的prvalue,“其中T是对象类型,可以转换为prvalue键入“指针   到 cv void“。将“指向 cv T”的指针转换为“指向 cv void的指针”的结果指向   类型为T的对象所在的存储位置,就好像该对象是类型最派生的对象(1.8)   T(即不是基类子对象)。空指针值转换为空指针值   目的地类型。

与3.9 / 8 [basic.types]一起:

  

对象类型是一种(可能是cv限定的)类型,不是函数类型,不是引用类型,而不是   void类型。

(强调我的)

使用/Za禁用扩展程序将禁用非标准转换。