C++ 模板中的自定义函数
Custom Functions in C++ Template
如果我使用带有 int 模板参数的 C++ class,例如:
template<int width> class ap_uint { ... }
然后我明白我可以从这种类型的特定宽度创建特定的定义,例如:
typedef ap_uint<72> data_t;
但是,如果我想说定义一个常量并将其传入,我有什么选择(除了定义)?像这样说:
#define WIDTH 72
typedef ap_uint<WIDTH> data_t;
typedef ap_uint<WIDTH / 8> mask_t; // Does this even work?
此外,是否可以在模板参数选择中定义一个函数或使用现有函数?像这样:
#define SIZE 1024
typedef ap_uint<ceil(log(SIZE, 2))> addr_t;
如果可能的话,我可以自己编写函数。
模板参数必须是常量表达式。因此,您的选项包括 #define
、enum
、const int
和 constexpr int
以及 expressions/functions,它们会产生常量表达式(特别是 constexpr
函数)。 constexpr int
是现代 C++ 的实现方式。
WIDTH / 8
确实有效。
本质上它必须是编译时常量
一些观察,排名不分先后。
(1) 你标记了 C++11,所以不仅 typedef
而且(更好的,恕我直言)还有 using
using data_t = ap_uint<72>;
(2) 你也可以 "templatize" using
template <int I>
using data_t = ap_uint<I+3>;
(3) "does this even work?"
#define WIDTH 72
typedef ap_uint<WIDTH / 8> mask_t;
有效。
但是,鉴于您标记了 C++11,我建议避免使用 #define
并改用 constexpr
常量
constexpr auto WIDTH = 72;
using mask_t = ap_uint<WIDTH / 8>;
(4) "would it be possible to define a function or use an existing one in the template parameter selection"
C++11 之前的答案是:不。
但是你标记了 C++11 所以答案是:是的,但是函数必须是 constexpr
一个
例子
constexpr int foo (int a)
{ return a+3; }
constexpt int bar = 42;
using data_t = ap_uint<foo(bar)>; // compile: foo(bar) is a constant expression
int baz = 42;
using data_t2 = ap_uint<foo(baz)>; // compilation error! baz isn't a constant
// expression so foo(baz) isn't
(5) std::ceil()
和 std::log()
不是 constexpr
所以
#define SIZE 1024
typedef ap_uint<ceil(log(SIZE, 2))> addr_t;
不编译
(6) "I am fine having to write the functions myself, if that is even possible."
从 C++11 开始,这是可能的(示例参见第 (4) 点)。
不幸的是,只有从 C++14 开始才有可能编写复杂的 constexpr
函数。
在C++11中,一个constexpr
函数几乎只能包含(稍微简化)一条return
指令。
如果我使用带有 int 模板参数的 C++ class,例如:
template<int width> class ap_uint { ... }
然后我明白我可以从这种类型的特定宽度创建特定的定义,例如:
typedef ap_uint<72> data_t;
但是,如果我想说定义一个常量并将其传入,我有什么选择(除了定义)?像这样说:
#define WIDTH 72
typedef ap_uint<WIDTH> data_t;
typedef ap_uint<WIDTH / 8> mask_t; // Does this even work?
此外,是否可以在模板参数选择中定义一个函数或使用现有函数?像这样:
#define SIZE 1024
typedef ap_uint<ceil(log(SIZE, 2))> addr_t;
如果可能的话,我可以自己编写函数。
模板参数必须是常量表达式。因此,您的选项包括 #define
、enum
、const int
和 constexpr int
以及 expressions/functions,它们会产生常量表达式(特别是 constexpr
函数)。 constexpr int
是现代 C++ 的实现方式。
WIDTH / 8
确实有效。
本质上它必须是编译时常量
一些观察,排名不分先后。
(1) 你标记了 C++11,所以不仅 typedef
而且(更好的,恕我直言)还有 using
using data_t = ap_uint<72>;
(2) 你也可以 "templatize" using
template <int I>
using data_t = ap_uint<I+3>;
(3) "does this even work?"
#define WIDTH 72
typedef ap_uint<WIDTH / 8> mask_t;
有效。
但是,鉴于您标记了 C++11,我建议避免使用 #define
并改用 constexpr
常量
constexpr auto WIDTH = 72;
using mask_t = ap_uint<WIDTH / 8>;
(4) "would it be possible to define a function or use an existing one in the template parameter selection"
C++11 之前的答案是:不。
但是你标记了 C++11 所以答案是:是的,但是函数必须是 constexpr
一个
例子
constexpr int foo (int a)
{ return a+3; }
constexpt int bar = 42;
using data_t = ap_uint<foo(bar)>; // compile: foo(bar) is a constant expression
int baz = 42;
using data_t2 = ap_uint<foo(baz)>; // compilation error! baz isn't a constant
// expression so foo(baz) isn't
(5) std::ceil()
和 std::log()
不是 constexpr
所以
#define SIZE 1024
typedef ap_uint<ceil(log(SIZE, 2))> addr_t;
不编译
(6) "I am fine having to write the functions myself, if that is even possible."
从 C++11 开始,这是可能的(示例参见第 (4) 点)。
不幸的是,只有从 C++14 开始才有可能编写复杂的 constexpr
函数。
在C++11中,一个constexpr
函数几乎只能包含(稍微简化)一条return
指令。