如何在编译时将整数模板参数修改为非零值

How to modify integer template argument to nonzero at compile time?

本文关键字:参数 修改 非零值 整数 编译      更新时间:2023-10-16

如果我有这个代码:

template<int SIZE = 0>
class A {
public:
    union {
        int buf[MagicThing];
        /* ... */
    };
};

在C++中可以制作一些称为MagicThing的(宏?)以这种方式工作的:

  • 如果大小> 0,则魔术事物==大小
  • 如果大小 == 0,则魔术事物 == 1

在编译时?(理想情况下,一些简短的技巧,无需使用增强库等)

您可以使用

int buf[SIZE > 0 ? SIZE : 1];

你可以试试这个

int buf[SIZE == 0 ? 1 : SIZE]

并将SIZE设为无符号,或添加static_assert以检查大小是否为非负数。您没有指定当SIZE小于 0 时想要的行为。大概这不应该发生。

(如果 SIZE 始终为 0 或更大,请将其类型更改为无符号。

一个疯狂的示例解决方案,也许可以用作其他情况的想法(使用 C++11 的资源):

#include <iostream>
/* General case */
template<unsigned SIZE>
constexpr unsigned MagicThing()
{
   return SIZE;
}
/* Partial specialization when SIZE == 0 */
template<>
constexpr unsigned MagicThing<0>()
{
    return 1;
}
template<unsigned SIZE = 0>
class A {
public:
   int buf[MagicThing<SIZE>()];
   size_t size() const
   {
       return sizeof(buf) / sizeof(int);
   }
};
int main()
{
   A<0> a0;
   A<1> a1;
   A<5> a5;
   std::cout << a0.size() << " " << a1.size() << " " << a5.size() << std::endl;
}
/* Compilation and execution */
$ gcc -std=c++11 sample.cpp
$ ./a.out
1 1 5

其他(不是最简单的)可能性是,使用新的static_if指令,为以下标准C++14提出,下一个(我不确定我的语法是否正确):

template<unsigned SIZE = 0>
class A {
public:
   static_if (SIZE > 0)
     int buf[SIZE];
   else
     int buf[1];
   size_t size() const
   {
       return sizeof(buf) / sizeof(int);
   }
};