首页 > 解决方案 > 将函数分配给函数指针,常量参数正确性?

问题描述

我现在正在我的大学学习 C++ 和 OOP 的基础知识。我不是 100% 确定函数指针在分配函数时是如何工作的。我遇到了以下代码:

void mystery7(int a, const double b) { cout << "mystery7" << endl; }
const int mystery8(int a, double b) { cout << "mystery8" << endl; }

int main() {
    void(*p1)(int, double) = mystery7;            /* No error! */
    void(*p2)(int, const double) = mystery7;
    const int(*p3)(int, double) = mystery8;
    const int(*p4)(const int, double) = mystery8; /* No error! */
}

据我了解,p2andp3赋值很好,因为函数参数类型匹配并且 const-ness 是正确的。但是为什么p1andp4分配没有失败呢?将 const double/int 与非 const double/int 匹配不应该是非法的吗?

标签: c++parametersconstantsdeclarationfunction-declaration

解决方案


根据 C++ 标准(C++ 17、16.1 可重载声明)

(3.4) — 仅在存在或不存在 const 和/或 volatile 方面不同的参数声明是等效的。也就是说,在确定声明、定义或调用哪个函数时,将忽略每个参数类型的 const 和 volatile 类型说明符。

因此,在确定函数类型的过程中,以下函数声明的第二个参数的限定符 const 被丢弃。

void mystery7(int a, const double b);

函数类型是void( int, double ).

还要考虑以下函数声明

void f( const int * const p );

相当于下面的声明

void f( const int * p );

第二个 const 使参数成为常量(也就是说,它将指针本身声明为不能在函数内部重新分配的常量对象)。第一个 const 定义指针的类型。它不会被丢弃。

请注意,尽管在 C++ 标准中使用了术语“常量引用”,但引用本身不能与指针相反。也就是下面的声明

int & const x = initializer;

是不正确的。

虽然这个声明

int * const x = initializer;

是正确的并声明了一个常量指针。


推荐阅读