使用size_t类型变量初始化模板构造函数

时间:2018-06-13 15:10:47

标签: class c++11 templates size-t template-classes

我有一个类,带有模板构造函数:

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 个答案:

答案 0 :(得分:0)

编译器将能够使用

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数组。

答案 1 :(得分:0)

  

我想在运行时输入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,因此您可以认为使用这样的解决方案只是接受的数量{{1} }值非常有限。

显然,如果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