Respuesta
Un caso en el que se define una función, pero no nombra el parámetro se da en la de Scott Meyers "Eficaz C++, 3ª edición", artículo 47:
template<typename IterT, typename DistT>
void doAdvance(IterT& iter, DistT d,
std::random_access_iterator_tag)
{
iter += d;
}
se utiliza en:
template<typename IterT, typename DistT>
void advance(IterT& iter, DistT d)
{
doAdvance(iter, d,
typename std::iterator_traits<IterT>::iterator_category());
}
Básicamente, el tercer parámetro en doAdvance es un tipo no acompañado por un nombre de variable, es decir, es un parámetro sin nombre. Tener un parámetro sin nombre no es un problema, ya que ese argumento solo se usa durante la resolución de qué función sobrecargada usar. Discuto estos temas en this SO relacionada pregunta.
Cuando no está realmente usando el parámetro en la función, pero no quiere romper la firma del método público.
Alexandros ha dado un [muy buen ejemplo] (http://stackoverflow.com/questions/3348223/in-c-in-the-definition-of-functions-the-argument-identifiers-are-optional-in/3348345 # 3348345) para explicar por qué no te importa el objeto real, excepto que está ahí. – sbi
Creo que quiere decir en la declaración de funciones. En realidad, también puede omitir el nombre del identificador en la definición de funciones, pero esto causará un error de compilación si se usa el parámetro, que es probable que suceda.
En algunos casos, los compiladores advertirán de los parámetros no utilizados, a menos que deje el nombre del identificador como se muestra. También es potencialmente útil mostrar que un parámetro no se usa. Aparte de eso, no tengo idea. Ciertamente no puedes dejar el identificador desactivado si usas el parámetro.
Así es como el compilador diferencia los operadores de incremento de prefijo y prefijo: X operador ++() es prefijo, X operador ++ (int) es postfijo.
Como int nunca se utiliza realmente en el operador postfix, no hay ninguna razón para darle un nombre. Por lo general, esta es la razón por la que obtiene parámetros sin nombre, para sobrecargar una función u operador para significar dos cosas ligeramente diferentes. Este es un truco común en la metaprogramación de plantillas como se usa en Loki y Boost.
Es posible que desee dejar en claro al OP que la razón por la que funciona es debido a la resolución de sobrecarga ... aunque supongo que acabo de hacerlo. –
No, no lo es. Estas son firmas diferentes, es decir, los tipos de argumentos son diferentes. Lo que el OP está preguntando es sobre omitir el identificador de algún parámetro. – Juliano
¿Eh? Joel está mostrando cómo un compilador puede discriminar entre ++ i y i ++ utilizando un parámetro sin nombre. ¿De qué estás hablando? –
Lo haces cuando estás implementando una función de alguna firma, no necesitas el parámetro (bastante común en las jerarquías detrás de un resumen) y necesitas compilar sin advertencias. Dado que todos los proyectos se deben configurar para que se rompan cuando hay una advertencia, y esto viene MUCHO en OOP/GP, es algo muy, muy común de hacer. De hecho, es tan común que muchas bibliotecas tengan una macro mylibUNUSED() para una mejor legibilidad.
Tenga en cuenta que el hecho de que el compilador no se preocupa por el nombre de parámetro real viene del hecho de que se puede utilizar diferentes nombres de los parámetros para una función (plantilla) declaración 's que para su definición.
Esto es útil cuando tiene una biblioteca que envía como encabezados y como archivo lib y todos los que usan su API no tendrán que volver a compilar todo solo porque, dentro de la biblioteca, cambian los nombres de algunos parámetro (s). (Probablemente tiene que haber estado en un proyecto multi-MLoC C++ para apreciarlo.)
Los parámetros adicionales pueden ser utilizados por SFINAE, para resolución de sobrecarga o despacho dependiendo de las propiedades de tipo.
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
#include <boost/call_traits.hpp>
#include <iostream>
#include <string>
// use SFINAE enable this function for numerical types only
template <class T>
double foo(T t, typename
boost::enable_if<boost::is_floating_point<T> >::
type* dummy = 0) {
double x = static_cast<double>(t);
return x;
}
// use extra parameter for overload resolution
struct PlanA {};
struct PlanB {};
void bar(const PlanA&) {
std::cout << "using plan A...\n";
}
void bar(const PlanB&) {
std::cout << "using plan B...\n";
}
// use type traits to choose which function to call
template <typename T>
double fooBar(T t) {
return dispatch(t, boost::is_convertible<T, double>());
}
double dispatch(double t, const boost::true_type&) {
std::cout << "convertible to double\n";
return t+0.1;
}
template <typename T>
double dispatch(const T&, const boost::false_type&) {
std::cout << "not convertible to double\n";
return 0.0;
}
int main() {
foo(1.0);
// foo(1); won't compile
bar(PlanA());
bar(PlanB());
std::string name = "John Dow";
fooBar(1.0);
fooBar(name);
}
- 1. ¿Por qué esta prueba en particular podría ser útil?
- 2. SDK: ¿Qué es exactamente? ¿Cómo podría ser útil?
- 3. Args opcionales en funciones de MATLAB
- 4. Omisión de los parámetros de funciones opcionales en JavaScript
- 5. Obteniendo la dirección IP del cliente: REMOTE_ADDR, HTTP_X_FORWARDED_FOR, ¿qué más podría ser útil?
- 6. ¿Tiene esta característica C# un nombre y qué hace?
- 7. ¿Qué sucede con los identificadores en un programa?
- 8. Permisos opcionales para que una aplicación pueda mostrarse en todos los dispositivos y habilitar funciones opcionales en algunos?
- 9. ¿Cuáles son los usos de funciones virtuales puras en C++?
- 10. He hecho algo que podría ser útil para la comunidad. ¿Ahora que?
- 11. ¿Forzar a los constructores de argumento único a ser explícitos en C++?
- 12. Definición de los miembros estáticos en C++
- 13. ¿Cómo se relacionan los intérpretes escritos en C y C++ con los identificadores de las funciones C (++)?
- 14. ¿Por qué los nombres de argumento de función no son importantes en las declaraciones de C++?
- 15. ¿Qué son los métodos anónimos en C#?
- 16. ¿Qué hay de malo en esta definición de plantilla?
- 17. Funciones virtuales en constructores, ¿por qué los idiomas son diferentes?
- 18. ¿Cuál podría ser la causa de RejectedExecutionException
- 19. ¿Los identificadores de proceso no son negativos en Linux?
- 20. ¿Qué caracteres están permitidos en los identificadores de Perl?
- 21. ¿Pueden los operadores de asignación de C++ ser funciones gratuitas?
- 22. ¿Qué significa "e" en esta definición de función?
- 23. ¿Es esta una definición válida de Array 2D en C++?
- 24. Definición de clase parcial en C++?
- 25. ¿Cuándo podría la herencia múltiple ser la única solución razonable?
- 26. ¿Puedo dar un valor predeterminado a los parámetros o parámetros opcionales en las funciones de C#?
- 27. delegados opcionales en C#
- 28. operador de asignación (=) en el argumento del método de definición
- 29. ¿Por qué los parámetros opcionales C# 4 definidos en la interfaz no se aplican en la clase de implementación?
- 30. Funciones de Javascript y argumentos opcionales
Nota, esto solo es válido para C++ y no para C. Menciono esto por la etiqueta C. – quinmars
gracias, utilicé la etiqueta c para subrayar la diferencia. –
No es así como se usan las etiquetas. Si busco todos los temas etiquetados con "C", no espero encontrar temas que no sean relevantes para C. Eso no tiene sentido, así que eliminé la etiqueta. –