简体   繁体   English

重载决策中的const指针

[英]const pointers in overload resolution

GCC treats these two function declarations as equivalent: GCC将这两个函数声明视为等效:

void F(int* a) { }
void F(int* const a) { }

test.cpp: In function 'void F(int*)': test.cpp:在函数'void F(int *)'中:

test.cpp:235: error: redefinition of 'void F(int*)' test.cpp:235:错误:重新定义'void F(int *)'

test.cpp:234: error: 'void F(int*)' previously defined here test.cpp:234:错误:'void F(int *)'在此处定义

This makes some sense because a caller will always ignore the const in this case... it only affects the usage of the parameter 'a' inside of the function. 这有一定意义,因为在这种情况下调用者总是会忽略const ...它只会影响函数内部参数'a'的使用。

What I'm wondering is where (if anywhere) the standard says that it's specifically OK to discard qualifiers on pointers used as function arguments for the purpose of overload resolution. 我想知道的是标准在哪里(如果有的话)说,为了重载解析的目的,丢弃用作函数参数的指针的限定符是特别好的。

(My real issue is that I'd like to figure out where GCC strips these pointless qualifiers internally, and since the C++ frontend of GCC is littered with comments referencing the standard, the relevant section of the standard might help me find the correct spot.) (我真正的问题是我想弄清楚GCC在内部剥离这些毫无意义的限定符的地方,并且由于GCC的C ++前端充斥着引用标准的注释,标准的相关部分可能帮助我找到正确的位置。 )

Standard says in 8.3.5/3 that for the purposes of determining the function type any cv-qualifiers that directly qualify the parameter type are deleted. 标准在8.3.5 / 3中说,为了确定函数类型,任何直接限定参数类型的cv限定符都将被删除。 Ie it literally says that a function declared as 即字面意思是声明一个函数

void foo(int *const a);

has function type void (int *) . 函数类型为void (int *)

A pedantic person might argue that this is not conclusive enough to claim that the above declaration should match the definition like this one 一个迂腐的人可能会争辩说这不足以说明上述声明应该像这个定义那样匹配

void foo(int *a)
{
}

or that it should make the code with dual declaration (as in your example) ill-formed, since neither of these concepts are described in the standard in terms of function types . 或者它应该使具有双重声明的代码(如在您的示例中)形成错误,因为这些概念都没有在标准中根据函数类型进行描述。

I mean, we all know that these const were intended to be ignored for all external purposes, but so far I was unable to find the wording in the standard that would conclusively state exactly that. 我的意思是,我们都知道这些const是出于所有外部目的而被忽略的,但到目前为止,我无法在标准中找到最终确切地说明这一点的措辞。 Maybe I missed something. 也许我错过了什么。

Actually, in 13.1/3 it has a "Note" that says that function declarations with equivalent parameter declarations (as defined in 8.3.5) declare the same function . 实际上,在13.1 / 3中它有一个“注释”,表示具有等效参数声明的函数声明(如8.3.5中所定义)声明了相同的函数 But it is just a note, it is non-normative, which suggests that somewhere in the standard there should be some normative text on the same issue. 但这只是一个注释,它是非规范性的,这表明在标准的某个地方应该有一些关于同一问题的规范性文本。

I think it is basically as prohibited as this: 我认为这基本上是禁止的:

void foo(int a) {}
void foo(const int a) {}

const on non-references doesn't participate in overloading. 非引用的const不参与重载。

In fact you could even declare 事实上,你甚至可以宣布

void foo(int a);

and later define 然后定义

void foo(const int a) {}

where the constness is purely an implementation detail which the caller doesn't care about. 其中constness纯粹是调用者不关心的实现细节。

It's the same as: 它与以下相同:

void foo(int);
void foo(const int);

Being the same to the caller. 与来电者一样。 This is because the function is getting a copy by-value no matter what, so the caller doesn't care if it's thought of as const or not; 这是因为函数无论如何都会获得副本值,因此调用者不关心它是否被认为是const ; it makes no difference to it. 它没有任何区别。

It's not legal for the compiler to ignore such things, but there is no difference in overload resolution. 编译器忽略这些事情是合法的,但重载决策没有区别。 The const applies to the implementation of the function. const适用于函数的实现。

Illegal would be if the compiler treated: 如果编译器处理了非法的话:

void foo(int i)
{
    i = 5; // good
}

void foo(const int)
{
    i = 5; // lolwut?
}

The same, by ignoring the const . 同样,忽略了const

I believe it's the other way around. 我相信这是另一种方式。 Any pointer, even nonconst, can be treated like const :). 任何指针,甚至是nonconst,都可以像const :)一样对待。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM