Является ли сравнение функций-указателей законным - PullRequest
0 голосов
/ 29 июня 2018

Я хочу знать, допустимо ли сравнение (не только == и !=) указателей на функции, если обе функции имеют одинаковый тип или приводятся к void*.

Вот пример кода:

    #include <iostream>
    struct A { static void f(){} };
    struct B { static void f(){} };
    int main()
    {
        std::cout << reinterpret_cast<void*>(&A::f) << '\n';
        std::cout << reinterpret_cast<void*>(&B::f) << '\n';
        std::cout << (&A::f < &B::f) << '\n';
    }

GCC (http://coliru.stacked -crooked.com / a / c03b2d2dc528c197 ) и Clang (http://coliru.stacked -crooked.com / a / 3330f8e0b88cc523 ), похоже, в порядке с этим .

Может кто-нибудь указать мне на правильный отрывок в стандарте?

Спасибо!

1 Ответ

0 голосов
/ 29 июня 2018

Ваш пример может не скомпилироваться. Если он компилируется, это не гарантирует, что он будет работать как положено. На практике это, вероятно, будет.

Начиная с C ++ 11, преобразование указателей функций в указатели объектов условно поддерживается результатами, определяемыми реализацией. Условно поддерживаемые средства реализации могут выбирать, хотят ли они его поддерживать. Если они этого не делают, они могут просто выдать сообщение об ошибке.

Для реализаций, которые поддерживают его, очень мало что гарантировано о результате преобразования: все, что сказано, это то, что если оно поддерживается, вы можете преобразовать его обратно и получить исходное значение. Это ничего не значит о результатах равенства или сравнений.

[expr.reinterpret.cast] р8

8 Преобразование указателя функции в тип указателя объекта или наоборот поддерживается условно. Смысл такого преобразования определяется реализацией, за исключением того, что если реализация поддерживает преобразования в обоих направлениях, преобразование prvalue одного типа в другой тип и обратно, возможно, с другой квалификацией cv, должно давать исходное значение указателя.

Для значимых == и != сравнений, просто сравните напрямую.

[expr.eq] p3

[...]

(3.2) В противном случае, если оба указателя равны нулю, оба указывают на одну и ту же функцию или оба представляют один и тот же адрес, они сравниваются равными.
(3.3) В противном случае указатели сравниваются неравно.

Что касается <, обычные правила для < делают ваше сравнение таким же бессмысленным, как int i, j; &i < &j;:

[expr.rel] p4

4 Результат сравнения неравных указателей с объектами 86 определяется в виде частичного порядка в соответствии со следующими правилами:

[...]

(4.3) В противном случае ни один указатель не требуется для сравнения больше другого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...