简体   繁体   English

function 声明中使用的 `const` 关键字,或定义,或两者兼而有之?

[英]Is the `const` keyword used in function declaration, or definition or both?

void test(int& in);
void test(const int& in){

}

int main(){
 int a = 5; 
 test(a);
 return 0;
}

Above doesn't compile with a link error: undefined reference to `test(int&)' .上面没有编译链接错误: undefined reference to `test(int&)'

I have 3 questions on this:我对此有3个问题:

1- Why do we get a link error? 1-为什么我们会收到链接错误? is it because adding const to the definition makes it a completely different function?是不是因为在定义中添加了const会使其成为完全不同的 function? why would it work when not using references, ie this works fine:为什么不使用引用时它会起作用,即这很好用:

void test(int in);
void test(const int in){}
..
 int a = 5; 
 test(a);
..

2- Does const go in function declaration, or definition or both? 2- const go 是否在 function 声明中,或定义或两者兼而有之? Seems like the behaviour is different if references are used.如果使用引用,似乎行为会有所不同。

3- Does the const keyword on an argument say "the parameter passed to me should be a constant in the caller" or "this parameter is treated as a constant in this function scope, regardless of it being constant in the caller or not" . 3-参数上的const关键字是否说“传递给我的参数应该是调用者中的常量”“此参数在此 function scope 中被视为常量,无论它在调用者中是否为常量” I'm sure it's the latter but wanted to confirm.我确定是后者,但想确认一下。

In C++ the two functions: C++中的两个函数:

void test(int& in);
void test(const int& in);

are TWO different, overloaded functions.是两个不同的重载函数。 The first binds to "writeable" integers, the second - to constant ones.第一个绑定到“可写”整数,第二个绑定到常量。

In your code:在您的代码中:

int a = 5; 
test(a);

a is a modifiable object, hence void test (int &) is a better match from compiler perspective and it selects this function for a call. a是可修改的 object,因此void test (int &)从编译器的角度来看是更好的匹配,它选择这个 function 进行调用。

The reason why you are getting linker error is that you declared but not defined this function.您收到 linker 错误的原因是您声明但未定义此 function。

In both cases below the const function would have been selected:const function 以下的两种情况下,都将被选中:

int const a = 5; 
test(a);
test(10);

Additionally if you only had const version declared as below, it would have been selected as well:此外,如果您只有const版本声明如下,它也会被选中:

//void test(int &in);
void test(const int &in){}
..
 int a = 5; 
 test(a);
..

As for the second question in case of references - const goes both to declaration and definition as these are different functions.至于引用的第二个问题- const既用于声明又用于定义,因为它们是不同的功能。

With normal values there is NO difference between the two when declared:对于正常值,声明时两者之间没有区别:

void test(int in);
void test(const int in);

They refer to THE SAME function.他们指的是相同的 function。 The const version will prevent modification of the function parameter in function definition. const版本将阻止修改 function 定义中的 function 参数。

For the third one, when applied to references it means two things:对于第三个,当应用于引用时,它意味着两件事:

  1. A reference will be passed to a function and not a copy for an object.引用将传递给 function,而不是 object 的副本。
  2. When accompanied by a const it promises to the caller not to modify referenced object and prevents the function from doing so.当带有const时,它向调用者承诺不修改引用的 object 并阻止 function 这样做。

A function-definition is always also a function-declaration.函数定义始终也是函数声明。

Thus, to differentiate them, the latter is often called a forward-declaration if it is not also a definition.因此,为了区分它们,如果后者不是定义,则通常称为前向声明。

The function-signature used for overload-resolution derives from the function-declaration, and there are a few peculiarities in deriving it from the written source:用于重载解析的函数签名源自函数声明,并且从书面源中派生它有一些特殊性:

  1. Top-level cv-specifiers on argument-types are discarded.参数类型上的顶级 cv 说明符被丢弃。

  2. Top-level cv-specifiers on return-type are discarded if the type is not a class- or union-type.如果类型不是类或联合类型,则返回类型上的顶级 cv 说明符将被丢弃。 (A struct is a class-type.) struct是类类型。)

The function is not affected by these rules outside overload-resolution and matching declarations.除了重载解析和匹配声明之外,function 不受这些规则的影响。

Applied to your examples:应用于您的示例:

void test(int& in);
void test(const int& in) { // const is not top-level
// The above two declarations are for different functions

void test(int in);
void test(const int in){} // const is top-level
// Equivalent declarations above

A function definition is also a function declaration. function 定义也是 function 声明。 Thus, you declare two overloaded functions, but only one function is defined, has a body.因此,您声明了两个重载函数,但只有一个 function 被定义,有一个主体。

The compiler choses the first function, since a is not const and the first choice is the exact match.编译器选择第一个 function,因为a不是 const 并且第一个选择是完全匹配。

You get the linker error, since the first function has no definition, ie no body.您会收到 linker 错误,因为第一个 function 没有定义,即没有正文。

It's best to do both, as the const keyword is intended to hint at the user that the variable will not be modified.最好两者都做,因为const关键字旨在提示用户变量不会被修改。 I believe most compilers will treat a const type as a different type as well, so you'll have a compile error.我相信大多数编译器也会将const类型视为不同的类型,因此您会遇到编译错误。

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

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