Я хочу, чтобы N вводился во время выполнения и передавал его в качестве аргумента шаблона.
Краткий ответ: это невозможно.
Длинный ответ: как объяснено с помощью RСаху, параметр шаблона должен быть известен во время компиляции, поэтому для него невозможно использовать значение времени выполнения.
В вашем конкретном случае, если class x
не зависит от размера s
, но используйтетолько в конструкторе (?) ... если у вас ограниченное количество принятых s
значений (от 1 до 5, например), вы можете использовать switch
следующим образом
#include <memory>
#include <iostream>
template <std::size_t N>
struct foo
{
foo (int[N][N])
{ std::cout << "-- foo " << N << std::endl; }
};
struct bar
{
template <std::size_t N>
bar (int matrix[N][N])
{ foo<N> ob(matrix); }
};
int main ()
{
std::unique_ptr<bar> pOb;
std::size_t s;
std::cin >> s;
switch ( s )
{
case 1: int m1[1][1]; pOb.reset(new bar{m1}); break;
case 2: int m2[2][2]; pOb.reset(new bar{m2}); break;
case 3: int m3[3][3]; pOb.reset(new bar{m3}); break;
case 4: int m4[4][4]; pOb.reset(new bar{m4}); break;
case 5: int m5[5][5]; pOb.reset(new bar{m5}); break;
default: /* throw some exception ? */ break;
}
// do something with pOb
}
ThisКстати, в отдельных случаях размер матрицы известен как время компиляции, поэтому вы передаете значение времени компиляции в аргумент шаблона.
Но, как вы можете видеть, вы должны написать case
для каждого принятого значения s
, так что вы можете подумать, что использовать решение, подобное этому, это только количество принятых значений s
очень ограничен.
Очевидно, что если содержимое case
велико, вы можете разработать для него функцию шаблона.
Например, вы можете разработать baz()
функцииследующим образом
template <std::size_t N>
std::unique_ptr<bar> baz ()
{
int m[N][N];
/* do something for m */
return std::unique_ptr<bar>(new bar{m});
}
, поэтому switch
становятся
switch ( s )
{
case 1: pOb = baz<1>(); break;
case 2: pOb = baz<2>(); break;
case 3: pOb = baz<3>(); break;
case 4: pOb = baz<4>(); break;
case 5: pOb = baz<5>(); break;
default: /* throw some exception ? */ break;
}