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

时间:2014-02-14 13:52:04

标签: c++ templates compile-time

如果我有这段代码:

template<int SIZE = 0>
class A {
public:

    union {
        int buf[MagicThing];
        /* ... */
    };
};

可以在C ++中创建一些名为MagicThing的(宏?),它可以这样工作:

  • 如果SIZE&gt; 0然后MagicThing == SIZE
  • 如果SIZE == 0则MagicThing == 1

在编译时? (想要一些简短的技巧,无需使用升级库等。)

3 个答案:

答案 0 :(得分:4)

您可以使用:

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

答案 1 :(得分:4)

你可以试试这个

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

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

答案 2 :(得分:1)

(如果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);
   }
};