2012-05-14 11 views
6

¿Por qué no sigue permitido en C++C++ sobrecarga con uno const parámetro

#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; 
} 
+0

¿Cuál es la conexión entre su pregunta original y su edición? Las dos preguntas parecen no estar relacionadas. –

+0

He eliminado eso. – Avinash

Respuesta

5

No responde realmente a qué , pero se determina por la norma, §1.3.10

The information about a function that participates in overload resolution (13.3): the types of its parameters and, if the function is a class member, the cv- qualifiers (if any) on the function itself and the class in which the member function is declared.

Esto sólo significa que la fase de clasificación cv de los argumentos son ignorados en la resolución de sobrecarga.

Un ejemplo similar (pero no equivalente) con referencias funciona:

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

porque aquí los tipos son diferentes, el primer caso de ser una referencia a char, la segunda una referencia a const char (en oposición a una referencia const a char).

3

Cuando se trata de funcionar parámetros, char y char const son el mismo tipo de datos.

+1

No son del mismo tipo de datos. Los calificadores de cv simplemente no son considerados para la resolución de sobrecarga. – juanchopanza

3

Esto sigue siendo ambiguo. Cuando se llama con un argumento de carácter, una versión copiará el argumento y dirá "OK, puede cambiar la copia". El otro copiará el argumento y dirá "OK, no puede cambiar la copia". ¿Cómo se supone que el compilador debe saber si puede o no cambiar una copia de algo? Podría hacer bien o bien.

2

porque es ambigua cuando estás pasando como esto

s.Method('x');

qué versión debe pensar que ser llamado?

0

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

Debido const indica que la variable que tiene un valor de conjunto, que no puede ser cambiado después de la declaración. No es un tipo de datos diferente.

+0

Accesibilidad? ¿Cómo? Los calificadores de acceso hacen eso (privado/protegido/público), no los calificadores const-volátiles. – xtofl

+0

ya que no puede modificar el valor en una fecha posterior a la declaración. Tal vez el término que utilicé no era el mejor. Respuesta editada – CosminO

6

¿Por qué no se permite seguir en C++?
La razón es la misma que el compilador le da como un error de compilación:
¡Porque son ambiguos!

¿Por qué estos métodos son ambiguos?
Respuesta corta: porque el estándar C++ lo dice.

¿Cuál es la razón detrás de estos métodos sobrecargados que son ambiguos?
El compilador no sabe si la persona que llama quiere tratar el valor del argumento pasadocomo const o no, no hay manera para que el compilador para determinar que con la información a la mano.

nota el énfasis en paso por valor aquí, el argumento se pasa por valor, y por lo tanto la ambigüedad. Si el argumento fue pasado por referencia entonces el compilador sabe con certeza cómo la persona que llama quiere tratar el argumento porque entonces se está pasando el objeto real, y por lo tanto el compilador puede hacer una selección de la sobrecarga adecuada.

El siguiente ejemplo da una idea más clara de la explicación anterior.

Online Sample:

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


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

La norma dice que esas dos declaraciones son equivalentes (13.1.3):

Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called.

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)