类对象作为模板函数参数

时间:2018-06-14 16:59:02

标签: c++ c++11 templates constexpr

我的模板有问题,我对它们的了解肯定是有限的。 所以我有一个应该存储一些信息的课程:

class Q
{
    int integer;
    int fractional;
  public:
    constexpr Q(int i,int f) : integer(i),fractional(f) {}
    int get_i() const {return this->integer;}
    int get_f() const {return this->fractional;}
    constexpr int get_w() {return this->integer + this->fractional;}

    friend ostream& operator<<(ostream& os, const Q& q){ os << "Q" << q.integer << "." << q.fractional << " (w:" << q.integer + q.fractional << ")"; return os; }
};

然后我有我的模板功能。这只是一个例子,但它表明了这一点:

template <Q input_q, Q output_q,const unsigned int X_0_evaluated_bit> void calculate_stuff (const int max_iterations)
{ 
  std::array<Q,input_q.get_w()> input_queue_q;
}

最后主要(我使用SystemC库)我生成我想在函数中使用的常量对象Q

int sc_main(int argc, char *argv[])
{
  constexpr Q Q1_i = Q(1,10);
  constexpr Q Q1_o = Q(0,11);

  // Number of bits used to address the LUT for the initial value
  const unsigned int X_0_evaluated_bit = 5;

  // Number of iteration for the Newton-Raphson
  const int max_iterations = 2;

  calculate_stuff <Q1_i,Q1_o,X_0_evaluated_bit> (max_iterations);
  return 0;
}

如果我尝试编译,我会收到以下错误消息:

check_ac_one_over.cpp:31:13: error: ‘class Q’ is not a valid type for a template non-type parameter
 template <Q input_q, Q output_q,const unsigned int X_0_evaluated_bit> void calculate_stuff (const int max_iterations)
             ^
check_ac_one_over.cpp:31:24: error: ‘class Q’ is not a valid type for a template non-type parameter
 template <Q input_q, Q output_q,const unsigned int X_0_evaluated_bit> void calculate_stuff (const int max_iterations)
                        ^
check_ac_one_over.cpp: In function ‘void calculate_stuff(int)’:
check_ac_one_over.cpp:33:31: error: template argument 2 is invalid
   std::array<Q,input_q.get_w()> input_queue_q;
                               ^
check_ac_one_over.cpp:33:46: error: invalid type in declaration before ‘;’ token
   std::array<Q,input_q.get_w()> input_queue_q;
                                              ^
check_ac_one_over.cpp: In function ‘int sc_main(int, char**)’:
check_ac_one_over.cpp:102:64: error: no matching function for call to ‘calculate_stuff(const int&)’
   calculate_stuff <Q1_i,Q1_o,X_0_evaluated_bit> (max_iterations);
                                                                ^
check_ac_one_over.cpp:102:64: note: candidate is:
check_ac_one_over.cpp:31:76: note: template<<typeprefixerror>input_q, <typeprefixerror>output_q, unsigned int X_0_evaluated_bit> void calculate_stuff(int)
 template <Q input_q, Q output_q,const unsigned int X_0_evaluated_bit> void calculate_stuff (const int max_iterations)
                                                                            ^
check_ac_one_over.cpp:31:76: note:   template argument deduction/substitution failed:
check_ac_one_over.cpp:102:64: note: invalid template non-type parameter
   calculate_stuff <Q1_i,Q1_o,X_0_evaluated_bit> (max_iterations);
                                                                ^
check_ac_one_over.cpp:102:64: note: invalid template non-type parameter
make: *** [check_ac_one_over.o] Error 1

现在我不确定我尝试做的事情是否可行。有没有人有一些想法我怎么能让它发挥作用?

干杯,

斯特凡诺

2 个答案:

答案 0 :(得分:0)

  

有没有人有一些想法我怎样才能让它发挥作用?

我想,这不是一个好主意,但是......

错误消息很明确:

  

'class Q'不是模板非类型参数的有效类型

但是,在您的示例中,您不使用完整的Q对象:您使用input_q.get_w()的值。

所以我假设您可以传递模板参数而不是完整的Q对象,但只传递get_w()返回的int值,因此模板非类型有效参数。

Something(仅使用第一个模板参数;不知道使用另一个模板参数)

template <int input_dim>
void calculate_stuff (const int max_iterations)
 { 
   std::array<Q, input_dim> input_queue_q;
 }

您可以致电(将Q1_iget_w()计为constexpr

calculate_stuff<Q1_i.get_w()> (1);

但请注意

1)get_w()也应const,而不仅仅是constexpr

  constexpr int get_w() const {return this->integer + this->fractional;}

因为constexpr方法不会自动const(从C ++ 14开始),但constexpr对象也是const(因此无法使用{ {1}}如果未定义get_w()

2)如果你想要一个const的数组如下

Q

std::array<Q, input_dim> input_queue_q; 类型需要不带参数的构造函数;通过示例将默认值添加到构造函数

Q

答案 1 :(得分:0)

我找到了解决方案。它不是完美的,但它非常接近。而是使用对象我使用指向已成为全局变量的对象的指针:

class Q
{
    int integer;
    int fractional;
  public:
    constexpr Q(int i = 0,int f = 0) : integer(i),fractional(f) {}
    constexpr int get_i() const {return this->integer;}
    constexpr int get_f() const {return this->fractional;}
    constexpr int get_w() const {return this->integer + this->fractional;}

    friend ostream& operator<<(ostream& os, const Q& q){ os << "Q" << q.integer << "." << q.fractional << " (w:" << q.integer + q.fractional << ")"; return os; }
};


template <const Q *input_q,const Q *output_q,const unsigned int X_0_evaluated_bit> void calculate_stuff (const int max_iterations)
{ 
  std::array<Q,input_q->get_w()> input_queue_q;
}


constexpr Q Q1_i = Q(1,10);
constexpr Q Q1_o = Q(0,11);

int sc_main(int argc, char *argv[])
{

  // Number of bits used to address the LUT for the initial value
  const unsigned int X_0_evaluated_bit = 5;

  // Number of iteration for the Newton-Raphson
  const int max_iterations = 2;

  calculate_stuff <&Q1_i,&Q1_o,X_0_evaluated_bit> (max_iterations);
  return 0;
}

干杯。