【问题标题】:Using Many Arguments Without Duplicating Code在不重复代码的情况下使用多个参数
【发布时间】:2010-10-18 12:02:25
【问题描述】:

有没有办法在不重复代码的情况下按顺序使用这个函数中的每个参数?例如,第一次通过循环我想使用 R,下一次我想使用 L 等等。 valuestruct 的设置顺序与参数相同,因此 button 方法将返回等价bool 我需要根据 int i 的 currentbutton。如果有更好的方法来完成同样的事情也没关系。

int valuex=0;

void SetValue(bool &R,bool &L,bool &D,bool &U,bool &T,bool &S,bool &B,bool &A,bool &Y,bool &X,bool &W,bool &E,bool &G, bool &F) {

        bool value[4] = {true, false, true, false};
        bool currentbutton;

        for (int i=0; i < 12; i++) {
            currentbutton=valuestruct.button(i);

            if(currentbutton) {
                "I want to grab each argument in sequence here"=value[valuex];
                valuex++;
                if(valuex>ARRAYSIZE(value))
                    valuex=0;
            }
        }
    }

【问题讨论】:

    标签: c++ loops arguments


    【解决方案1】:

    如果您确实坚持使用此函数原型(并且不遵循此处传递数组或列表的其他建议 - 更好),您可以使用类似的东西 -

    void SetValue(bool &R,bool &L,bool &D,bool &U,bool &T,bool &S,bool &B,bool &A,bool &Y,bool &X,bool &W,bool &E,bool &G, bool &F)
    {
       bool* Bools[] = { &R, &L, &D, &U, &T, &S, &B, &A, &Y, &X, &W, &E, &G, &F };
    
       // *Bools[i] can be used to access the ith element.
    
       // Print the 4th element.
       std::cout << *Bools[3];
    
       // Change the value of the 5th.
       *Bools[4] = true;
    }
    

    顺便说一句,如果您确实不需要更改传递的值,则不应通过引用传递它们。通过引用传递布尔值只会浪费时间和空间。这也将使这里的代码不那么混乱。

    【讨论】:

      【解决方案2】:

      您是否考虑过使用布尔数组? :) 收藏绝对是要走的路。如果您需要保留元数据以过滤或获取某些值,请考虑使用 Map。

      【讨论】:

        【解决方案3】:

        还是bit field?快速脏版:

        int field = FLAG_R | FLAG_L
        
        void SetValue(int fields) {
            for (int i = 0; i < FLAG_COUNT; i++) {
                if (fields & (1 << i)) {
                    // Flag #i is set
                }
            }
        }
        

        编辑

        顺便说一句,如果您不更改值,则将布尔值作为参考传递是无用的。用于引用的指针可能比保存 bool 本身的类型长。

        【讨论】:

          【解决方案4】:

          您可以使用可变参数支持,因为您有固定数量的参数,您知道要循环多少。 IIRC 它实际上并不要求函数具有可变参数。

          va_list args;                                                                                                     
          va_start(args,R);
          // your code here...
          va_end();
          

          请原谅我的错误……我已经有好几年没有主动编写 C 代码了。

          【讨论】:

          • 为什么它被否决了?很可能它也适用于固定参数 - 它们以与可变参数相同的方式位于堆栈中。
          • C 可变参数宏和 C++ 引用不能混用。 " 警告:无法通过‘...’接收非 POD 类型‘bool&’的对象;调用将在运行时中止”
          • 知道了,没有注意到 C++ 引用。对于纯 C,它应该可以工作。
          • OP 甚至需要变量作为参考吗?我不这么认为,因为该调用称为“设置值”(另一条评论基本上也指出了这一点)。这将在没有引用的情况下工作。在我的书中 +1。
          • 每个参数依次是替换字符串“我想在这里按顺序抓取每个参数”的左值,所以它们必须是引用。
          【解决方案5】:

          我会将此添加到 hexagon 的答案中,但我还不能编辑帖子。

          int valuex=0;
          
          void SetValue(bool &R,bool &L,bool &D,bool &U,bool &T,bool &S,bool &B,bool &A
                       ,bool &Y,bool &X,bool &W,bool &E,bool &G, bool &F) 
          {
              bool* bools[] = { &R, &L, &D, &U, &T, &S, &B, &A, &Y, &X, &W, &E, &G, &F };
              bool value[4] = {true, false, true, false};
              bool currentbutton;
          
              for (int i=0; i<12 && i < ARRAYSIZE(bools); i++) {
                      currentbutton=valuestruct.button(i);
          
                      if(currentbutton) {
                              *bools[i]=value[valuex];
                              valuex++;
                              if(valuex>ARRAYSIZE(value))
                                      valuex=0;
                      }
              }
          }
          

          虽然我不明白在哪里认为您只会读取布尔值,但您可能不会设置所有这些值。

          【讨论】:

            【解决方案6】:

            您可以将参数放入一个数组并传递该数组。根据调用代码是什么,这可能会导致代码更少。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-10-21
              • 2021-09-11
              • 1970-01-01
              • 1970-01-01
              • 2022-01-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多