Подтвердить что ты не робот

G++ "вызывает" функцию без скобок (не f(), но f;). Почему он всегда возвращает 1?

В С++ (GNU GCC g++) мой код "вызывает" функцию без(). Функция не работает, но компилируется нормально.

Более удивительно, что код всегда возвращает 1...

Есть ли какие-либо объяснения?

Я ожидал, что имя функции будет просто регулярным указателем, но кажется немного другим...

Получил ли я все 1 только случайно?

#include <iostream>
using namespace std;

void pr ()
{
    cout << "sth";
}

int main()
{

pr;
cout << pr;  // output: 1
cout << *pr; // output: 1
cout << &pr; // output: 1

}
4b9b3361

Ответ 1

Фактически вы не вызываете pr в свой код, вы передаете указатель на cout. pr затем преобразуется в bool при передаче в cout. Если вы положили cout << boolalpha заранее, вы выведете true вместо 1.

EDIT:
С С++ 11 вы можете написать следующую перегрузку:

    template <class RType, class ... ArgTypes>
    std::ostream & operator<<(std::ostream & s, RType(*func)(ArgTypes...))
    {
        return s << "(func_ptr=" << (void*)func << ")(num_args=" 
                 << sizeof...(ArgTypes) << ")";
    }

что означает, что вызов cout << pr будет печатать (func_ptr=<address of pr>)(num_args=0). Сама функция может делать то, что вы хотите, очевидно, это просто, чтобы продемонстрировать, что с помощью вариативных шаблонов С++ 11 вы можете сопоставлять указатели функций произвольной arity. Это все равно не будет работать для перегруженных функций и шаблонов функций, не указывая, какую перегрузку вы хотите (обычно с помощью трансляции).

Ответ 2

Имя функции, которая используется без круглых скобок, может быть неявно передана указателю на функцию. Фактически, когда вы разыскиваете ссылку или ссылаетесь на нее, она остается не чем иным, как указателем на функцию, или poointer для указателя на функцию и т.д. Эти указатели на функции при печати неявно отображаются на bool, поэтому они просто выводят 1 Если вы хотите вывести фактический адрес памяти функции, наведите его на указатель void:

cout<<(void*)pr;