为什么在函数参数常量预选赛用于重载分辨率? [重复](Why are const qualifi

2019-07-30 14:51发布

可能重复:
与常量参数和重载函数

我敢在重载和常量声明规则混淆。 这里有两件事情让我困惑,也许你能帮我找到我的头更深的误解,导致他们成为令人费解给我。 ;)

首要问题:

我的编译器允许这样的:

void f(int & x) {
  std::cout << "plain f" << std::endl;
}
void f(const int & x) {
  std::cout << "const f" << std::endl;
}

但是,以下原因编译错误(功能已经具备了身体):

void f(int x) {
  std::cout << "plain f" << std::endl;
}
void f(const int x) {
  std::cout << "const f" << std::endl;
}

这一点我想是有道理的,因为我认为const的在那里只告诉传递的对象没有改变,在第二种情况下被复制反正编译器。 但是,如果这是正确的,那么我为什么可以使用常量重载函数?

换句话说,为什么如果我使用的编译版本,并调用函数如下:

  int x1 = 5;
  const int x2 = 5;
  f(x1);
  f(x2);

做我得到“纯F”和“常量F”,而不是“常量F”两次? 显然,我现在还使用const告诉其功能不仅使参考不改变调用编译器。 这得到更加混乱,因为如果我删除了“普通”版本,它工作得很好,并呼吁“常量”版本的两倍。

那么什么是我的实际问题? 我想知道这背后的行为思想,否则记住这是很难。

Answer 1:

我以为常量在那里只告诉传递的对象没有改变编译器和在第二种情况下它也会被复制

你是对的。 因为在第二情况下,它无论如何复制,所以const使得给呼叫者没有差别,该标准定义了void f(const int x)void f(int x)具有相同的签名。 因此,他们碰撞,你想两次定义相同的功能。

因为在第一种情况下它被复制无论如何, void f(const int &x)void f(int &x)具有不同的签名。 因此,他们超载。

在你第一种情况下,它被禁止调用int&版本fx2作为参数,因为这会在没有任何视线明确的转换创建一个非const引用const对象。 这样做违背了常量系统(这是,如果你想打破const的安全,你有一个投来明确地这样做)的目的。 所以很有意义的参考参数的函数const-和非const重载。

在第二个的情况下,有副本源的常量性,以及目的地的常量性之间没有任何关系。 您可以从一个非const一个,或从一个const一个非const一个初始化一个const变量。 这会导致任何问题,并且不破坏const的安全。 这就是为什么标准的有益说明了这一点通过定义你的两个“不同”版本f实际上是相同的功能。



Answer 2:

n3337 13.1

[注:如在8.3.5中所规定,具有等效参数声明函数声明声明相同的功能,因此不能被重载:FFER仅在存在或不存在

- 参数的声明该常量的DI3和/或挥发性是等价的。 也就是说,对于每个参数类型的常量和挥发性类型说明符确定正在声明其功能,定义,或调用时被忽略。 [实施例:

 typedef const int cInt; int f(int); int f(const int); // redeclaration of f(int) int f(int) { /* ... */ } // definition of f(int) int f(cInt) { /* ... */ } // error: redefinition of f(int) 

- 端示例]只有常量,并在参数类型specifica-灰以这种方式被忽略的最外层挥发性类型说明符; 常量和掩埋的参数类型规范内波动类型说明符显著,并且可以用来区分重载函数declarations.124特别地,对于任何类型的T,“指针至T”,“指针为const T,”和“指针易失性T”被认为是不同的参数类型,因为是‘参考至T’,‘参考常量T,’和‘参照挥发性T.’



文章来源: Why are const qualifiers in function arguments used for overloading resolution? [duplicate]