6

为什么不允许关注C++

#include <iostream>

class Sample {
public:
  void Method(char x);
  void Method(char const x);
};

void Sample::Method(char x) {
  char y = x;
}

void Sample::Method(char const x) {
  char y = x;
}

int main() {
  Sample s;
  return 0;
}
4

7 回答 7

6

为什么在 C++ 中不允许跟随?
原因与编译器给您的编译错误相同:
因为它们是模棱两可的!

为什么这些方法模棱两可?
简短的回答:因为 C++ 标准是这样说的。

这些重载方法模棱两可的原因是什么?
编译器不知道调用者是否想要将传递的参数的值视为一个const或不,编译器无法根据手头的信息来确定这一点。

请注意这里强调按值传递,参数是按值传递的,因此存在歧义。如果参数是通过引用传递的,那么编译器肯定知道调用者想要如何处理参数,因为实际对象本身正在被传递,因此编译器可以选择适当的重载。

下面的例子对上面的解释给出了一个更清晰的概念。

在线样品

class Sample 
{
    public:
        void Method(char &x){}
        void Method(char const x){}
        void Method(char const &x){}
};


int main() 
{
     Sample s;
     return 0;
}
于 2012-05-14T11:45:03.967 回答
5

它并没有真正回答为什么,但它由标准决定,§1.3.10

关于参与重载决议 (13.3) 的函数的信息:其参数的类型,如果函数是类成员,则函数本身的 cv 限定符(如果有)和成员函数所在的类宣布。

这只是意味着参数的 cv 限定符在重载决议中被忽略。

一个类似(但等效)的示例与参考作品:

class Sample {
public:
  void Method(char& x) {}
  void Method(const char& x) {}
};

因为这里的类型不同,第一种情况是对 的引用char,第二种是对的引用const char(而不是对 的const引用char)。

于 2012-05-14T11:35:28.797 回答
3

说到函数参数,charchar const都是同一个数据类型。

于 2012-05-14T11:33:33.540 回答
3

这仍然是模棱两可的。当使用字符参数调用它时,一个版本将复制参数并说“好的,你可以更改副本”。另一个将复制参数并说“好的,您不能更改副本”。编译器应该如何知道它是否可以更改某些内容的副本?它可以做得很好。

于 2012-05-14T11:33:42.130 回答
2

因为当你像这样经过时它是模棱两可的

s.Method('x');

你认为应该叫什么版本?

于 2012-05-14T11:33:49.540 回答
2

该标准说这两个声明是等效的(13.1.3):

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

typedef const int cInt;

int f(int);
int f(const int);            // redeclaration of f(int)
int f(int) { /* ... */ }     // definiton of f(int)
int f(cInt) { /* ... */ }    // error: redefiniton of f(int)
于 2012-05-14T11:49:00.430 回答
0

http://duramecho.com/ComputerInformation/WhyHowCppConst.html

因为const表示该变量具有设定值,所以在声明后无法更改。它不是不同的数据类型。

于 2012-05-14T11:34:11.943 回答