2010-06-27 14 views
8

Si ve este código,Cuando todo el operador de coma no actúa como un operador de coma?

class A{ 
public: 
    A(int a):var(a){} 
    int var; 
}; 

int f(A obj) { 
    return obj.var; 
} 

int main() { 
    //std::cout<<f(23); // output: 23 
    std::cout<<f(23, 23); // error: too many arguments to function 'int f(A)' 
    return 0; 
} 

f(23, 23) no se compila porque la coma actúa como un separador de aquí y no como un operador coma.

Donde todos hacen una coma no funcionan como un operador de coma? ¿O al revés?

Respuesta

11

Desde un punto de vista gramatical, los parámetros de una llamada de función forman una expresión-lista opcional dentro de paréntesis. Una lista de expresiones consiste en una o más asignación-expresión separadas por un token de coma. Una coma solo puede significar un operador de coma donde se espera una expresión .

El operador coma hace un expresión de un expresión, un , y un asignación-expresión, pero un expresión participación de operador coma no es en sí mismo un asignación-expresión así puede' t aparece en una lista de expresiones excepto cuando es un componente de algo que es una expresión de asignación .

Por ejemplo, puede rodear cualquier expresión (incluyendo uno usando el operador de coma) dentro de paréntesis, a partir de una primaria-expresión que es un asignación-expresión y por lo tanto válido en un expresión-lista .

E.g.

postfix-expresión donde el expresión-lista se compone de dos asignación-expresión cada uno de los cuales es un identificador.

f(a, b); 

postfix-expresión donde el expresión-lista consta de un solo asignación-expresión que es un primaria-expresión que es un paréntesis expresión usando el operador de coma.

f((a, b)); 
8

El uso de la ficha coma como un operador es distinta de su uso en llamadas a funciones y definiciones, declaraciones de variables, enum declaraciones, y construcciones similares, donde actúa como un separador.

Wikipedia - Comma operator

+4

¿Cuáles son los "constructos similares"? – Philipp

+0

@Philipp: Básicamente, esos constructos en los que la gramática describe explícitamente el significado de la coma. La lista anterior omite, por ejemplo, las declaraciones de miembros y amigos, que son muy similares a las declaraciones de variables. Otro ejemplo sería una expresión de objeto temporal como 'Complex (0,1)' que es similar a una llamada a función. – MSalters

+0

+1 para una respuesta súper concisa. – stinky472

1

Un operador coma siempre actúa como un operador coma, pero una coma no siempre significa un operador coma - A veces es sólo puntuacion.

En cuanto a cuándo es la puntuación, la respuesta simple es "cuando el estándar así lo dice". Pasar por todas las situaciones donde dice el estándar da una respuesta mucho más larga, pero una que es poco probable que sea mucho más útil, porque (por ejemplo) tiene que lidiar con varios casos de esquina a la mayoría de las personas no les importa mucho acerca de.

7

Esto tiene que ver con la definición del lenguaje de expresiones, que es bastante complejo.

f(1, 2) es una expresión de llamada de función con dos parámetros. Por el contrario, f((1, 2)) es una expresión llamada de función con un parámetro, que es la sub-expresión 1, 2, que evaluará a 2.

+0

¡Porque la coma es un operador aquí! Se devuelve el resultado de la expresión más a la derecha. Solo para aclarar a cualquier lector –

8

Hice una búsqueda sobre el borrador del estándar. Básicamente, en la gramática, las producciones -list son las que tienen comas en ellas para separar diferentes elementos. Los siguientes resultados son específicos de C++ 03. En C++ 0x, expression-list delega directamente en initializer-list porque en C++ 0x las listas de llaves pueden aparecer en la función y en los argumentos del constructor de la misma manera.

  • expresión lista de Para función argumentos/constructor (incluyendo yesos funcionales)
  • empadronador-lista La lista de elementos de una enumeración
  • init-declarador-lista Los diferentes nombres declarados en una declaración

    Ejemplo:

    int a, b; 
    
  • declaración-parámetro-list El parámetro lista de declaración (¡sorpresa!) De una función
  • inicializador lista lista similar a la lista de expresión, pero puede incluir listas de expresiones reforzadas. Se utiliza para la inicialización de agregados (arrays o estructuras de inicialización)
  • miembro-declarador lista Similar a la lista declarador init, pero para declaraciones de miembros en las clases.

    Ejemplo:

    struct A { int a, b; }; 
    
  • base especificador-listaLista de bases clases de una clase.
  • mem-inicializador-lista Lista de los inicializadores para miembros

    Ejemplo:

    struct A { A():a(0), b(0) { } int a; int b; }; 
    
  • plantilla-parámetro-list lista de parámetro de plantilla declaraciones.
  • plantilla-argumento-lista Lista de argumentos de plantilla pasados ​​a una plantilla.
  • tipo-id-lista Lista de los tipos para especificaciones de excepción

    Ejemplo:

    void f() throw(int, bool) { } 
    

Hay una identificador-lista para los parámetros de macro también, que i no han figurado en esa lista porque es realmente parte de la gramática del preprocesador.

Cuestiones relacionadas