g ++“调用”一个没有括号的函数(不是f()而是f;)。为什么它总是返回1?

时间:2013-06-12 18:48:51

标签: c++ g++

在c ++(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

}

2 个答案:

答案 0 :(得分:14)

您实际上并未在代码中调用pr,而是将函数指针传递给cout。在传递给pr时,bool会转换为cout。如果事先提出cout << boolalpha,则会输出true而不是1

修改
使用C ++ 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)。函数本身可以做任何你想要的事情,这只是为了证明使用C ++ 11的可变参数模板,你可以匹配任意arity的函数指针。这仍然不适用于重载的函数和函数模板,而没有指定您想要的过载(通常通过强制转换)。

答案 1 :(得分:4)

当没有括号使用时,函数的名称可以隐式地转换为函数指针。事实上,当你取消引用或引用它时,它仍然只是一个函数指针,或函数指针的指针等。这些函数指针在打印时被隐式转换为bool,这就是为什么它们只是输出1.如果要输出函数的实际内存地址,请将其转换为void指针:

cout<<(void*)pr;