2012-04-20 26 views
10

Escuché que la volatilidad es un factor de sobrecarga como const.sobrecarga volátil?

Si una función está sobrecargada por un parámetro volátil, ¿cuándo se llama a la versión volátil?

No me puedo imaginar una situación cuando se llama a la versión volátil.  

+0

Agregado C++ etiqueta; Si ese no es el idioma del que está hablando, edite su pregunta para mencionar ese hecho bastante importante y volver a organizarlo apropiadamente. – Mat

+2

Esto es similar a 'const', si tiene un objeto calificado' volátil' entonces solo se puede invocar a la función 'volátil'. –

+1

oh, me olvidé –

Respuesta

8

Volatile se puede aplicar a los parámetros, pero no es un factor de sobrecarga cuando se aplica directamente al parámetro. Sin embargo, es posible usarlo para distinguir los tipos del parámetro. Por ejemplo, esto es legal:

void f(int &p) {}; //reference to int 
void f(volatile int &p) {}; //reference to volatile int 

Esto no es:

void f(int p) {}; 
void f(volatile int p) {}; 

La razón es que en el primer ejemplo de la referencia no es lo que es volátil, pero el número entero. En el segundo ejemplo, ambos tipos son enteros y, por lo tanto, del mismo tipo.

También hay métodos volátiles. Son similares a declarar que this es volátil. Debido this es un puntero y no el tipo que contiene, lo siguiente es también legal:

void c::f(int p) {}; 
void c::f(int p) volatile {}; 

Todo es la misma que para la sobrecarga por const.

Esta parte relevante del estándar de C++ es §13.1 Declaraciones sobrecargables. Desde C++ 11 borrador n3290:

Las declaraciones de los parámetros que difieren solo en la presencia o ausencia de const y/o volátil son equivalentes. Es decir, los especificadores de tipos const y volátiles para cada tipo de parámetro se ignoran al determinar qué función se declara, define o llama. [Ejemplo:

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) 

- ejemplo final]

Sólo el const y volátiles de tipo especificadores en el nivel más exterior de la especificación del tipo de parámetro se ignoran de esta manera; Los especificadores de tipos const y volátiles enterrados dentro de una especificación de tipo de parámetro son significativos y se pueden usar para distinguir las declaraciones de función sobrecargadas . En particular, para cualquier tipo T, pointer to T, pointer to const T y pointer to volatile T se consideran tipos de parámetros distintos, como reference to T, reference to const T y reference to volatile T.

124) Cuando un tipo de parámetro incluye un tipo de función, como en el caso de un tipo de parámetro que es un puntero a función, el const y volátiles de tipo especificadores en el nivel más exterior de las especificaciones de tipo parámetro para el tipo de función interna es también ignorado.

+0

Esa es una buena respuesta – Pete

10

He aquí un ejemplo:

#include <iostream> 

struct A { 
    void foo() { 
     std::cout << "in non-volatile" << std::endl; 
    } 
    void foo() volatile { 
     std::cout << "in volatile" << std::endl; 
    } 
}; 

int main() 
{ 
    A a; 
    a.foo(); 
    volatile A b; 
    b.foo(); 
} 

b.foo() llamará a la sobrecarga de volatile. Si struct A no tuviera una sobrecarga volátil para foo, b.foo() no sería válido.

+0

No tan rápido. Esta pregunta parece ser sobre parámetros volátiles, y esos no son un factor de sobrecarga. –

+0

Eso no estaba (no está) del todo claro para mí, y Pete ya publicó una respuesta sobre los parámetros de la función. – Mat

+0

Estoy bien con eso, pero @Pete tampoco me da la respuesta completa. Tal vez deberíamos consolidarnos. –

3

Escriba un programa de prueba para descubrir.

void func(const int& a) 
{ 
    std::cout << "func(const)" << std::endl; 
} 

void func(const volatile int& a) 
{ 
    std::cout << "func(const volatile)" << std::endl; 
} 

int main() 
{ 
    const int a = 0; 
    const volatile int b = 0; 
    func(a); 
    func(b); 
    system("pause"); 
    return 0; 
} 

salida voluntad:

func(const) 
func(const volatile)