std ::已知序列的载体

时间:2009-12-17 00:21:25

标签: c++ vector

我正在尝试通过“C ++方式”做所有事来学习C ++。我正在编写一个程序,其中包含所有这些已知值(在编译时)。这是我的问题:

在我的构造函数中,我想检查传递的值(一个int)是否是2,4,8,16或32中的一个,否则抛出一个错误。我想说的是:

  1. 制作C样式数组或整数
  2. 手工创建矢量并通过它进行交互以检查
  3. 列出清单?我之前从未使用过列表。
  4. 我真正想做的是在单独的头文件中创建一个const向量,但这似乎不可能。

    这种检查最优雅的方式是什么?

    此外,类似地,是否有任何方法可以在标题中创建具有已知值(在编译时)的设定数量的向量?如果我可以做const std::string a_str("a string");我不明白为什么我不能对矢量使用类似的技术。

6 个答案:

答案 0 :(得分:8)

出了什么问题:

if (!(n == 2 || n == 4 || n == 8 || n == 16 || n == 32))
{
    // no!
}

如果你想要“C ++方式”,静态数组应该用find

template <typename T, size_t N>
T* endof(T (&pArray)[N])
{
    return &pArray[0] + N;
}

static const int OkNumbers[] = {2, 4, 8, 16, 32};
static const int* OkNumbersEnd = endof(OkNumbers);
if (std::find(OkNumbers, OkNumbersEnd, n) == OkNumbersEnd)
{
    // no!
}

修改此列表很简单,我猜测编译器可以将其优化为我之前的答案。

答案 1 :(得分:6)

这有点戏法,但我相信这有效:

if (n & (n-1) != 0)
{
   // not a power of two
}

答案 2 :(得分:2)

如果我们谈论的是愚蠢的话,这是我的尝试:

if ((n & 0x3E) != n || (n & n - 1) != 0)
  throw std::runtime_error("not a power of two less than or equal to 32");

有点狡猾的愚蠢是非常C / C ++,但只有“优雅”,如果优雅,你的意思是“尽可能少的处理器周期,尽可能简洁的语法”。使用字典查找或显式检查(例如在GMan的答案中使用std :: find),否则。

可读性几乎总是偏向于这种古怪。

答案 3 :(得分:1)

如果你真的想用矢量做它并希望好的赋值操作看一下boost :: assign。

但你真的不想用矢量来做;)

编辑:我刚看到你的“编译时”。考虑为什么不能这样做:std::vector不是内置类型。要有一种机制来使用某种智能分配,就需要为整个语言和每个用户定义的类型内置支持它。即使您不需要核心语言支持并且可以使用模板,这也不符合STL的整体风格。

答案 4 :(得分:0)

使用普通的C数组,我的C生锈但是这里

int array[] = {2,4,8,16,32};

/* now loop over the array and check */

for( i = 0; i< size_of_array ; i++) {
  if (array[i] == input_int) 
  /* you get the idea ..... */

答案 5 :(得分:0)

这可能不符合您尝试执行的操作,但您可以使用枚举。

由于这是编译时知识,我将假设这些传递的值在编译时很重要。使用枚举,调用者不会试图找出传递给你的函数的幻数。

typedef enum 
{
  Value1 = 2,
  Value2 = 4,
  Value4 = 8,
  Value5 = 16,
  Value6 = 32

} MyMagicType;

void MyFunction(MyMagicType theType)
{
...
}

然后,编译器会强制该值成为上述之一(好吧,除非你强制转换它,但这是另一回事)并且如果它不是定义的值之一则抛出错误。