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

已知序列的向量 我试图通过做“C++方式”来学习C++。我正在编写一个程序,其中包含所有这些已知值(在编译时)。我的问题是:,c++,vector,C++,Vector,在我的构造函数中,我想检查传递的值(int)是否为2、4、8、16或32之一,并以其他方式抛出错误。我想: 生成C样式数组或整数 手动创建一个矢量,并通过它进行交互检查 列个清单?不过我以前从未使用过列表 我真正想做的是在一个单独的头文件中创建一个const向量,但这似乎是不可能的 最优雅的检查方式是什么 同样,是否有任何方法可以使一个向量在头中具有一组已知值(在编译时)?如果我能做const std::string a_str(“字符串”)我不明白为什么我不能对向量使用类似的技术。有什么问题:

在我的构造函数中,我想检查传递的值(int)是否为2、4、8、16或32之一,并以其他方式抛出错误。我想:

  • 生成C样式数组或整数
  • 手动创建一个矢量,并通过它进行交互检查
  • 列个清单?不过我以前从未使用过列表
  • 我真正想做的是在一个单独的头文件中创建一个const向量,但这似乎是不可能的

    最优雅的检查方式是什么


    同样,是否有任何方法可以使一个向量在头中具有一组已知值(在编译时)?如果我能做
    const std::string a_str(“字符串”)我不明白为什么我不能对向量使用类似的技术。

    有什么问题:

    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!
    }
    
    模板
    T*endof(T(&pArray)[N])
    {
    返回和阵列[0]+N;
    }
    静态常量int OkNumbers[]={2,4,8,16,32};
    静态常数int*OkNumbersEnd=endof(OkNumbers);
    if(std::find(OkNumbers,OkNumbersEnd,n)=OkNumbersEnd)
    {
    //不!
    }
    

    修改此列表很简单,我猜编译器可能会根据我之前的答案对此进行优化。

    这有点技巧,但我相信这是可行的:

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

    如果你真的想用向量来做,并且想要很好的赋值操作,那么看看boost::assign

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


    编辑:我刚看到你的“在编译时”。考虑为什么不能这样做:<代码> STD::vector < /COD>不是内置类型。要想有一种机制来使用某种智能赋值,就需要为整个语言和每个用户定义的类型提供内置的支持。即使您不需要核心语言支持,并且可以使用模板来实现,这也与STL的整体风格不一致。

    使用普通的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 ..... */
    
    int数组[]={2,4,8,16,32};
    /*现在在数组上循环并检查*/
    对于(i=0;i<数组的大小;i++){
    if(数组[i]==input\u int)
    /*你明白了*/
    
    这可能不适合您尝试执行的操作,但您可以使用枚举

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

    typedef enum 
    {
      Value1 = 2,
      Value2 = 4,
      Value4 = 8,
      Value5 = 16,
      Value6 = 32
    
    } MyMagicType;
    
    void MyFunction(MyMagicType theType)
    {
    ...
    }
    

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

    如果我们谈论的是位旋转愚蠢,那么下面是我的尝试:

    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)


    <>他对这种古怪的行为几乎总是可取的。

    他想做“C++方式”这不是C++代码。任何一个只为检查几个数字而设置的列表的人,做的工作太多了,我想,我并不是说它不是C++,他说他想做“C++方式”。这到底意味着什么。我同意这是太多的工作,但他可能只是为了练习而不是
    endof
    方法,试试这个:
    OkNumbersEnd=OkNumbers+sizeof(OkNumbers)/(OkNumbers[0])
    可以在编译时计算,不需要模板。你的代码更详细,我的代码也在编译时。模板不是坏事。我想他只需要OP中列出的5个数字。也许范围检查会合适。
    0==0x0000
    不是二的幂。
    (0-1)==-1==0xffff
    ,而
    0x0000&0xffff==0x0000==0
    ,这不是
    !=0
    。因此,您的逻辑中存在一些缺陷。hhafez:嗯,添加
    (n>32)
    比较很简单。如果要排除64个及以上(和1),您可以轻松地明确检查它们。
    If(n&(n-1)&&n>=2&&n@ndim-这不是一个完美的检查,但它可能更有效(并且更易于维护)而不是针对每个特定值进行测试。std::string不是内置类型,您在问题中给出的代码不会在编译时创建字符串。它会在运行时创建一个字符串,并使用C样式的字符串文本对其进行初始化。std::string恰好有一种很好的初始化方法,而vector没有。C++0x将引入初始化器列表,它将允许您执行
    std::vector v={1,2,3};
    std::vector v2={“1”,“2”,“3};
    否。您引用的构造函数将const char*作为参数。此指针取自字符串文字“a string”。字符串文字是“内置”的。是的,但当devin说“是字符串内置类型”时答案必须是“否”。通过“string”,他要么意味着“std::string”(这不是内置类型),要么意味着“string literal”(这根本不是一种类型)。在我上面的评论中,我说“string”的地方,我指的是“std::string”,除了我说的“C-style string literal”。“我不明白为什么我不能对向量使用类似的技术。”类的初始化列表。我相信这是一个计划中的“c++0x”特性。还没有在标准中。。。