如何解决用于模板中传递的cpp结构变量
我只想问问cpp中作为模板参数传递变量是否有任何用途
template<int a> struct foo {
int x = a;
};
int main() {
foo<2> bar;
std::cout << bar.x;
}
像这样的东西可以编译,工作和cout
的2,但是可以通过做同样的事情
struct foo {
int x;
foo(int a) : x(a) {}
};
int main() {
foo bar(2);
std::cout << bar.x;
}
那么在模板参数中使用变量有什么意义呢?我还可以看到使用第一种方法的一个大缺陷:变量a
使用内存,并且在更改x
之后不会被破坏,就像在第二个示例中调用构造函数之后一样。如果您对此做了一些合理的使用,可能会有所帮助。
解决方法
当您通过模板参数传递变量时,可以在编译时使用它。
例如,如果需要在类中创建静态大小的数组,则可以使用template参数传递数组的大小:
template <int TSize>
class Foo {
[...] // Do whatever you need to do with mData.
private:
std::array<int,TSize> mData;
};
,
模板参数中的常量有很多用途。
静态大小
这就是您开始实施std::array
之类的方式的方法。
template <typename T,size_t SIZE>
struct Array {
T data[SIZE];
}
模板参数始终在constexpr
上下文中可用,因此它们可用作静态大小的数组的大小。
为算法提供编译时参数
另一个用途是参数化算法,如以下代码示例中所示。
我们有一个uint32_t
顺序的ARGB
,但是要将其存储在文件中,我们可能需要将其重新排序为BGRA
或RGBA
。我们在编译时就知道顺序,因此我们可以使用ArgbOrder
模板变量。
enum class ArgbOrder { ARGB,RGBA,BGRA };
struct ChannelOffsets {
unsigned a;
unsigned r;
unsigned g;
unsigned b;
};
// and we can get a constexpr lookup table from this enum
constexpr ChannelOffsets byteShiftAmountsOf(ArgbOrder format)
{
...
}
template <ArgbOrder order>
void encodeArgb(uint32_t argb,uint8_t out[4])
{
// We can generate the shift amounts at compile time.
constexpr detail::ChannelOffsets shifts = shiftAmountsOf(order);
out[0] = static_cast<u8>(argb >> shifts.a);
out[1] = static_cast<u8>(argb >> shifts.r);
out[2] = static_cast<u8>(argb >> shifts.g);
out[3] = static_cast<u8>(argb >> shifts.b);
}
void example() {
encodeArgb<ArgbOrder::BGRA>(12345);
}
在此示例中,我们可以在编译时选择适当的查找表,并且运行时成本为零。在运行时只需要进行4个班次即可。
功能切换
我们可以使用bool
模板变量来切换代码中的功能,例如:
template <bool handleZeroSpecially>
int div(int x,int y) {
if constexpr (handleZeroSpecially) {
return y == 0 ? 0 : x / y;
}
else {
return x / y;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。