【问题标题】:Class object as template funciton argument类对象作为模板函数参数
【发布时间】:2018-11-24 12:42:16
【问题描述】:

我对模板有疑问,我对它们的了解绝对有限。 所以我有一个类应该存储一些信息:

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;
}

最后,我在 main(我使用 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

现在我不确定我正在尝试做的事情是否可行。有没有人有一些想法我怎样才能让它工作?

干杯,

斯特凡诺

【问题讨论】:

  • 你为什么把你的函数变成一个模板?您可能在一条糟糕的道路上被卡住了一半,而帮助您继续前进将是一种伤害。
  • 好吧,我没有讲完所有的故事。在模板化函数内部还有其他几个模板化函数。这些函数必须被模板化,它们代表硬件模块(我使用的是 SystemC 库)。使用 SystemC 库编写硬件时必须遵循一些规则,即使从 RTL 中的 C++ 转换的工具非常挑剔。
  • 这并不能解释为什么外部函数需要是模板。此外,还有一个名为“GIGO”的经典编程概念,在这种情况下,如果你问一个不完整的问题,你会得到不完整的答案。

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


【解决方案1】:

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

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

错误信息很清楚:

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

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

所以我想你可以作为模板参数而不是完整的Q 对象传递,而只能传递get_w() 返回的值,即int,因此作为模板非类型参数是有效的。

某事(仅使用第一个模板参数;不知道如何使用另一个)

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(所以如果没有定义,就不能使用get_w() const)

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

std::array<Q, input_dim> input_queue_q;

Q 类型需要一个不带参数的构造函数;例如,将默认值添加到您的构造函数

constexpr Q(int i = 0, int f = 0) : integer(i),fractional(f) {}

【讨论】:

  • 我想,这是我的第一个方法。我想以其他方式做,以保持清洁和简单的设置。只是为了澄清一点。这种方法不是我唯一使用的方法。我基本上在函数 2 Q 对象中使用,从我现在需要的整数和小数。所以它将是一个至少有 4 个参数的模板化函数......这不是很优雅。
  • 我想解决方案是将该参数转换为指针。在这种情况下,它应该是一个有效的非类型,我应该能够做我想做的事。对吧?
  • @haster8558 - 为了保持干净......这些值必须在非静态成员中吗?静态 constexpr 成员的集合呢?这样你就可以传递一个类型名。
【解决方案2】:

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

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;
}

干杯。

【讨论】:

  • 我不会说这接近于完美的解决方案,尽管您可能会开始一条富有成效的道路。试试这个作为练习:将Q1_iQ1_o 的定义移到模板函数上方。接下来,将x_0_evaluated_bit 的定义移动到全局范围,将其放在Q1_o 的定义之后。现在删除文本template &lt;const Q *input_q,const Q *output_q,const unsigned int X_0_evaluated_bit&gt;&lt;&amp;Q1_i,&amp;Q1_o,X_0_evaluated_bit&gt;。将input_q-&gt;get_w() 更改为Q1_i.get_w()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
相关资源
最近更新 更多