Generar una secuencia de ceros en tiempo de compilación
Tengo el siguiente problema:
template< size_t... N_i >
class A
{
public:
// ...
void foo()
{
bar( /* 0,...,0 <- sizeof...(N_i) many */);
}
};
Quiero llamar a una función bar
y pasarle sizeof...(N_i)
muchos argumentos que son todos ceros, por ejemplo, bar(0,0,0)
en el caso sizeof...(N_i) == 3
.
¿Cómo se puede aplicar esto?
3 answers
bar(((void)N_i, 0)...);
El operador de coma descartará N_i
, produciendo solo el valor del operando de la derecha (0
). El lanzamiento es para evitar una advertencia sobre N_i
ser descartado.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-24 12:46:49
A pesar de la indudablemente interesante respuesta de @Columbo , quiero sugerir otra solución viable basada en constexpr
variables de plantilla'd:
#include <cstddef>
template<std::size_t, std::size_t V>
constexpr std::size_t repeat_value = V;
template<std::size_t... N_i>
class A {
template<typename... Args>
void bar(Args&&...) { }
public:
void foo() {
// repeat N_i times value 0
bar(repeat_value<N_i, 0>...);
}
};
int main() {
A<0, 1, 2, 3, 4> a;
a.foo();
}
Me resulta más fácil de leer al menos, incluso si es malo en términos de rendimiento en tiempo de compilación.
Puedes generalizarlo fácilmente de la siguiente manera:
template<std::size_t, typename T, T V>
constexpr T repeat_value = V;
La invocación en el caso específico es la siguiente:
bar(repeat_value<N_i, int, 0>...);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:07
También puedes usar plantillas para simular algo similar. Esta es una solución muy básica y solo creará una lista de 0s, pero podría ampliarse para generar otras secuencias si se desea.
template <size_t Unused>
struct Wrap {
static constexpr size_t value = 0;
};
template <size_t... N_i>
class A {
public:
void foo() {
bar(Wrap<N_i>::value...);
}
};
Que simplemente se expandirá en una lista de ceros del mismo tamaño que los argumentos N_i. Es cierto que la interfaz es ligeramente diferente.
Para un ejemplo completo, que muestra los valores de los elementos que recibe bar, vea aquí: Ejemplo en vivo
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-24 14:35:47