variable una publicas programación programacion numeros lenguaje inicializacion dev declarar declaracion declara cómo como arreglos c++ variadic-functions

una - ¿Cómo puedo crear un constructor de C++ que acepte un número variable de int?



lenguaje de programacion c variables (4)

Has actualizado tu pregunta para indicar que todo lo que necesitas es un std::integer_sequence tiempo de compilación, lo cual es genial.

Pero solo por el bien de los futuros lectores que podrían venir aquí buscando la respuesta, también me gustaría responder a su pregunta original: "¿Es posible restringir el tipo de argumentos en un constructor variadic?"

Sí. Una forma (¿la mejor manera? No estoy seguro) es a SFINAE en un parámetro de plantilla adicional, como este:

struct X { template< class... TT, class E = std::enable_if_t<(std::is_same_v<TT, int> && ...)> > X(TT... tt) { // do stuff with the ints "tt..." } };

El && ... es un pliegue-expresión, nuevo en C ++ 17. Si su compilador no admite expresiones de plegado, simplemente sustitúyalo por un all_of .

¿Es posible restringir el tipo de argumentos en un constructor variadic?

Quiero poder expresarme

X x1(1,3,4); X x2(3,4,5); // syntax error: identifier ''Args'' class X { template<int ... Args> X(Args...) { } }; // this works but allows other types than int class Y { template<typename ... Args> Y(Args...) { } };

editar para aclarar la intención:

Lo que quiero lograr es almacenar los datos pasados ​​a un constructor (constantes conocidas en tiempo de compilación) en una matriz estática.

así que hay algunos otros

template<int ...values> struct Z { static int data[sizeof...(values)]; }; template<int ... values> int Z<values...>::data[sizeof...(values)] = {values...};

y en el constructor de XI me gustaría usar Z así:

class X { template<int ... Args> X(Args...) { Z<Args...>::data // do stuff with data } };

¿Es eso posible, nuestro tengo que usar integer_sequence?


No, no puedes restringir el tipo. Puedes usar static_assert sin embargo. Sería algo como esto:

static_assert(std::is_same<int, Args>::value ..., "have to be ints.");

static_assert embargo, no he intentado usar una expansión en un static_assert así. Es posible que necesites un constexpr que devuelva bool o algo así.


Puedes usar std::initializer_list :

#include <iostream> #include <initializer_list> void myFunc(std::initializer_list<int> args) { for (int i: args) std::cout << i << ''/n''; } int main(){ myFunc({2,3,2}); // myFunc({2,"aaa",2}); error! }


Ya que tienes lo siguiente:

template<int... values> struct Z { static int data[ sizeof...( values ) ]; }; template <int... values> int Z<values...>::data[ sizeof...( values ) ] = { values... };

Puede usar std::integer_sequence<> para pasar las entradas a Z<> :

struct X { template <int... values> X( std::integer_sequence<int, values...> ) { for ( int i{ 0 }; i < sizeof...( values ); ++i ) Z<values...>::data[ i ]; // do stuff with data } };

Puedes convertirte en un tipo de ayudante para que sea más fácil llamar al ctor:

template <int... values> using int_sequence = std::integer_sequence<int, values...>;

Entonces puedes crear una instancia de tu clase así:

int main() { X x( int_sequence<1, 3, 5>{} ); }