Инициализация конструктора шаблона с переменной типа size_t

У меня есть класс с конструктором шаблона:

class x
{
  public:

    template<std::size_t N>
    x(int matrix[N][N])
     {
        A<N> ob(matrix);
     }
};

в основной функции:

int main()
{
   size_t s;
   cin >> s;
   int m[s][s];

   x ob(m); // error
}

ошибка:

ошибка: нет подходящей функции для вызоваx::x(int [s][s])"|

Я хочу создать массив, размер которого указан пользователем, и перейти к x::x() который использует его для создания объекта класса шаблона. A определяется как:

template<size_t N>
class A
{
 ...
};

Любые решения этого, я хочу N быть введенным во время выполнения и передать его в качестве аргумента шаблона. На самом деле я хотел передать это непосредственно A но это дает ошибку: non-const template arguementвот я и подумал о создании A в другом классе, но ошибка тоже есть.

Я использую кодовые блоки 16.01.

2 ответа

Я хочу, чтобы N вводился во время выполнения и передавал его как аргумент шаблона.

Краткий ответ: это невозможно.

Длинный ответ: как объяснил R Sahu, параметр шаблона должен быть известен во время компиляции, поэтому для него невозможно использовать значение времени выполнения.

В вашем конкретном случае, если 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
 }

Таким образом, в отдельных случаях размер матрицы известен как время компиляции, поэтому вы передаете значение времени компиляции в аргумент шаблона.

Но, как вы можете видеть, вы должны написать 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;   
 }

Компилятор сможет использовать

template<std::size_t N>
x(int matrix[N][N]) { ... }

только если N известен во время компиляции.

Когда вы используете

size_t s;
std::cin >> s;
int m[s][s];

x ob(m); // error

это неправда. Значение s может быть известно только во время выполнения. Компилятор справедливо сообщает об этом как об ошибке.

Вы можете удалить ошибку компилятора, изменив объявление конструктора или изменив способ использования конструктора. Из вашего поста не ясно, что вы пытаетесь сделать с аргументом конструктора. Следовательно, я не могу предложить конкретное решение.

я хочу N для ввода во время выполнения и передачи его в качестве аргумента шаблона.

Это невозможно. Все параметры шаблона должны быть известны во время компиляции. Вам придется изменить свой дизайн, чтобы вы могли использовать тип контейнера, размер которого можно определить во время выполнения, например: std::vector, Вы можете использовать std::vector<std::vector<int>> эмулировать 2D-массив.

Другие вопросы по тегам