功能过载和ODR如何共存?(C )



为什么在编译单元中定义同名的多个功能不违反一个定义规则?编译器如何识别违反ODR和代码的代码之间使用哪个功能过载的代码?

在c 中,定义 include 参数类型(以及c 17,异常规格(。

因此,超载是可能的,因为即使名称相同,功能也不相同。

一个定义规则意味着必须定义每个超载函数一次。因此没有矛盾。每个过载函数以某种方式有所不同,例如参数的数量或类型,存在或不存在C/V限定符(在参数声明或类成员函数本身中(等等。

有时初学者将这些功能声明视为过载函数的声明

的声明
void f( int a[100] );
void f( int a[10] );
void f( int a[] );
void f( int *a );

但是,编译器隐式将数组类型的参数调整为数组元素类型的指针。

您可以在程序中包含所有这些(冗余(声明,但必须仅定义一次。

因此,上面的声明声明相同的一个函数,由编译器调整为int *类型的参数。

考虑到这些功能声明声明两个超载函数

void f( int *a );
void f( const int *a );

(这里指针本身不是恒定

这两个声明

void f( int x );
void f( const int x );

声明相同的一个函数,因为当编译器确定函数是否被超载或相同时,const限定符会丢弃。

当功能参数具有函数类型时,可能会出现相同的混乱。例如

void f( void g() );
void f( void ( *g )() );

再次,编译器隐式地将函数类型的参数调整为指向函数的指针。

这是一个指示的程序

#include <iostream>
void f( void g() );
void f( void ( *g )() );
void g() { std::cout << "Hello Philippa Richtern"; }
void f( void g() )
{
    g();
}
int main()
{
    f( g );
}

其输出是

Hello Philippa Richter

请注意,该函数f是定义一次,尽管该函数被声明了三遍,包括声明同时是其定义。

一个定义规则不是适用于具有相同名称的事物;它适用于假装相同的事物。

两个名为 foo的类(在全局范围内声明,在命名空间,类或功能之外(假装相同;他们必须一样。如果您更改一个程序中的定义,则对编译器撒谎。(这就像根据术语的特殊定义与某人争论,然后假装证明了适用于常规条款的某些东西。(

两个名为 bar的功能不假装是相同的,除非它们具有相同的参数列表。

相关内容

  • 没有找到相关文章

最新更新