2011-02-23 13 views
5

Asumamos que quiere hacer esto en C++ 0x:funciones variadic (sin argumentos!)

size_t count_int() { return 0; } 
template<typename T, typename... Tn> 
size_t count_int(T a0, Tn... an) { 
    size_t n = is_integer<T>::value ? 1 : 0; 
    return n + count_int(an...); 
} 

Niza, pero se siente innecesario pasar alrededor de los argumentos. Por desgracia, esto no funciona:

size_t count_int() { return 0; } 
template<typename T, typename... Tn> 
size_t count_int() { 
    size_t n = is_integer<T>::value ? 1 : 0; 
    return n + count_int<Tn...>(); 
} 

GCC se queja de error: ninguna función coincidente para la llamada a 'count_int()' en la línea siguiente a la última. ¿Por qué y cómo se puede arreglar esto? Gracias.

Respuesta

1

No funciona porque no tiene ningún caso base cuando el paquete de parámetros no contiene valores, ya que el caso base count_int() que utilizó anteriormente no está templado y no puede invocarse con <Tn...>, incluso cuando Tn está vacío. Es por eso que falla. En cuanto a cómo se puede arreglar, tengo poca idea.

1

Esto se debe a que la condición de detención no es una plantilla de función, por lo que cuando llama al count_int<Tn...>(); con un Tn vacío, no se encuentra la función sin plantilla.

Si intenta cambiar la condición de parada a una plantilla:

template <typename...> 
size_t count_int() { return 0; } 

Usted obtendrá un error ya que es ambiguo, que la función que está llamando cuando hacer tienen parámetros en el paquete de parámetro.

Puede resolver esto reenviando la llamada a una clase de plantilla y evitar la recursividad por completo. Algo parecido a lo siguiente debería funcionar (aunque no he conseguido hacerlo aún)

template <typename T, typename... Tn> 
struct int_counter { 
    enum { value = is_integer<T>::value + int_counter<Tn...>::value; } 
}; 

template <> 
struct int_counter<> { 
    enum { value = 0; } 
}; 

template <typename... Tn> 
size_t count_int() { 
    return int_counter<Tn>::value; 
} 
3

Este works:

template <typename T> 
size_t count_int() 
{ 
    return is_integer<T>::value ? 1 : 0; 
} 

template<typename T, typename T1, typename... Tn> 
size_t count_int() { 
    size_t n = is_integer<T>::value ? 1 : 0; 
    return n + count_int<T1,Tn...>(); 
}; 
+0

Gracias! Eso funciona bien – Hans

Cuestiones relacionadas