匹配bool的函数的地址vs const void * overload [英] The address of a function matching a bool vs const void* overload

查看:268
本文介绍了匹配bool的函数的地址vs const void * overload的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读意外值使用随机数生成器作为函数在C ++ 和注释和当前答案说,用户正在输出的函数的地址。听起来合情合理。我假设发生了一个函数到指针转换,因此匹配 const void * 重载,但是当我自己测试时,导致GCC / Clang与MSVC。以下测试程序:

I'm reading Unexpected value using random number generator as a function in C++ and the comments and current answer say that the user is outputting the address of the function. That sounded reasonable. I assumed that a function-to-pointer conversion was occurring and therefore matching the const void* overload, however upon testing it myself, I get different results in GCC/Clang vs MSVC. The following test program:

#include <iostream>

void test()
{
}

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

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

int main()
{
    func(test);
}

输出 bool GCC / Clang( coliru

outputs bool in GCC/Clang (coliru)

const void * http://rextester.com/live/QNFXT35340rel =nofollow> rextester 警告实时协作链接)

and const void* in MSVC (rextester warning live collaboration link)

N3337 说:

[conv.func]

[conv.func]


的函数类型 T 可以转换为
类型的prvalue指向 T 。结果是指向该函数的指针。

An lvalue of function type T can be converted to a prvalue of type "pointer to T." The result is a pointer to the function.

[conv.bool]

[conv.bool]

可以将算术,无范围枚举,指针或指向
成员类型的prval值转换为 bool 。零
值,空指针值或空成员指针值将
转换为 false ;任何其他值将转换为 true
std :: nullptr_t 类型的prval值可以转换为bool类型的prvalue;
的结果值是 false

A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. A prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.

不是空指针值转换为bool应等于 true ,解释由GCC / Clang给出的警告。

So a pointer which is not a null pointer value converted to bool should equal true, explaining the warning given by GCC/Clang.

然后表12 [over.ics.scs]下的转换提供了一个函数到指针的转换,完全匹配排名和布尔转换转换排名。 [over.ics.rank] / 4然后说:

Then Table 12 Conversions under [over.ics.scs] gives a function-to-pointer conversion an "Exact Match" rank and boolean conversions "Conversion" rank. [over.ics.rank]/4 then says:


标准转换序列按其排名排序:an Exact
Match是一种更好的转化,而不是促销,这是比转化更好的
转化。具有相同
排名的两个转换序列是无法区分的,除非以下规则之一适用:

Standard conversion sequences are ordered by their ranks: an Exact Match is a better conversion than a Promotion, which is a better conversion than a Conversion. Two conversion sequences with the same rank are indistinguishable unless one of the following rules applies:


一个指针,指向成员的指针,
std :: nullptr_t bool

- [...]

— [...]



$ b b

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

I am not a language lawyer so I hope that I quoted the right sections.

然而MSVC会调用 const void * 重载,即使 bool overload不存在,反之亦然:GCC / Clang将调用 bool 重载,即使 const void * 重载不存在。所以我不清楚在这里的转换。

However MSVC will call the const void* overload even if the bool overload is absent, and vice versa: GCC/Clang will call the bool overload even if the const void* overload is absent. So I'm not clear on the conversions here. Can somebody clear this up for me?

推荐答案

看起来像MSVC中的错误(或扩展名)。该标准没有定义从指针到函数到指向 void 的任何标准转换。

Seems like a bug (or extension) in MSVC. The standard does not define any standard conversions from a "pointer to function" to a "pointer to void."

很难为某事的缺席提供报价,但我能做的最接近的是C ++ 11 4.10 / 2 [conv.ptr]:

It's hard to provide a quote for the absence of something, but the closest I can do is C++11 4.10/2 [conv.ptr]:


指向 cv T 的类型的prvalue $ c> T 是一个对象类型,可以转换为类型为指针
cv 的prvalue 。将指向 cv T 的指针转换为指向 cv void 指向
的开始位置 T 类型的对象所在的存储位置,就像对象是最大派生
T类型的对象(1.8)(即不是基类子对象)。空指针值将转换为
目标类型的空指针值。

A prvalue of type "pointer to cv T," where T is an object type, can be converted to a prvalue of type "pointer to cv void". The result of converting a "pointer to cv T" to a "pointer to cv void" points to the start of the storage location where the object of type T resides, as if the object is a most derived object (1.8) of type T (that is, not a base class subobject). The null pointer value is converted to the null pointer value of the destination type.

与3.9 / 8 .types]:

Together with 3.9/8 [basic.types]:


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

An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not a void type.

(强调我)

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

Using /Za to disable extensions will disable the non-standard conversion.

这篇关于匹配bool的函数的地址vs const void * overload的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆