2012-03-09 26 views
9

Solo para estar seguro, por lo que he leído y probado, ¿no puedo poner un argumento predeterminado en una plantilla de función correcta? He recogido tanto de mi compilador Y de lo que otros han respondido con ... Lo estoy preguntando porque soy un principiante y algunas de las respuestas más técnicas son difíciles de entender. ¿Hay una solución para esto? Estoy intentando crear una función encontrarMax que utiliza un operador de relación por defecto pero con la opción de sobrecargar ... es decir:Argumento predeterminado en la plantilla de función C++

template <typename Type, typename Compare = std::less<Type> > 
Type FindMax(std:vector<Type> &vec, Compare comp = Compare()) { 
    return *std::max_element(... 
} 

supongo que podría hacer una clase para esto, pero parece que un montón de trabajo cuando todo lo que realmente quiero es una función ... ¡Gracias!

debo añadir otra pregunta así por algo que yo he visto antes:

¿Qué hace esta función tempate, específicamente, ¿cuál es la (cmpFn) ...) argumento predeterminado haciendo?

template <typename ElemType> 
    ElemType FindMax(Vector<ElemType> &v, int (cmpFn)(ElemType, ElemType) = OperatorCmp) 
+0

Posible duplicado de * [Valor predeterminado de la función de plantilla C++] (http://stackoverflow.com/questions/3301362/c-template-function-default-value) *. –

Respuesta

8

Hay una serie de cosas que decir:

  1. Lo que ha definido es una plantilla función, no una plantilla de clase . Dado que está utilizando un parámetro de plantilla por defecto

    typename Compare = std::less<Type>

    supongo que ya está usando C++ 11, porque por lo que sé plantillas de función no permitieron a los parámetros de plantilla por defecto en las versiones anteriores de la norma .

  2. Por otro lado, los argumentos por defecto de los parámetros de plantilla como esta

    Compare comp = Compare()

    eran posibles en la versión anterior de la norma, también. Su afirmación de que los argumentos predeterminados no son posibles para los parámetros de plantilla es incorrecta (o tal vez se refiere a lo que llamé parámetros de plantilla por defecto arriba).

  3. El mensaje de error del compilador que recibe debe deberse a algún otro problema. Quizás el Type que termina usando no va bien con std::less, o el tipo Compare que utiliza no implementa el constructor predeterminado. En cualquier caso, el siguiente programa compila en GCC 4.6.2 (tenga en cuenta que he cambiado el std::vector<> &-const std::vector<> & porque parecía más a la derecha):

 

#include <vector> 
#include <functional> 
#include <algorithm> 

template <typename Type, typename Compare = std::less<Type> > 
Type FindMax(const std::vector<Type> &vec, Compare comp = Compare()) { 
    return *std::max_element(vec.begin(),vec.end(),comp); 
} 

int main() { 
    FindMax(std::vector<int>()); 
    return 0; 
} 

Y de hecho esto requiere la opción -std=C++0x, pero eso es porque el parámetro de plantilla por defecto, no se el argumento predeterminado.

Sobre la cuestión adicional relacionada con cmpFn:

que declara un parámetro de la función , es decir, un argumento que es en sí mismo una función. La declaración

int (cmpFn)(ElemType, ElemType) 

significa el nombre local de la función es cmpFn, su tipo de retorno es int, y toma dos argumentos, ambos de tipo ElemType. La idea es que la persona que llama puede pasar una función (o un functor) que luego se usará para comparar los elementos del vector. P.ej. si se define el valor por defecto de este argumento OperatorCmp antes de la declaración de la función así:

int OperatorCmp(int a, int b) { 
    return (a<b?-1:(a>b?1:0)); 
} 

la declaración quede válida y se puede usar para encontrar el valor máximo de una std::vector<int>.

+0

Gracias. Esa segunda parte es lo que estaba buscando solo que no me di cuenta ... un parámetro de función. – MCP

+1

Nota: 'cmpFn' no se puede usar con' std :: max_element' porque espera un resultado booleano (similar a '<'), no un resultado ternario. –

5

Puede hacerlo en C++ 11. A partir de C++ 03, puede solucionarlo fácilmente creando dos sobrecargas con diferentes números de argumentos y reenviando de uno a otro.

template <typename Type> 
Type findMax(std::vector<Type> const & v) { 
    return findMax(v, std::less<Type>()); 
} 

Como alternativa, puede utilizar los algoritmos estándar y evitar tener que escribir los suyos propios.

Cuestiones relacionadas