【问题标题】:Pass an object as parameters to a function in C++将对象作为参数传递给 C++ 中的函数
【发布时间】:2012-02-27 14:48:07
【问题描述】:

在 Javascript 或 ActionScript 中,可以将对象传递给函数或构造函数。

myfunction({myParam:1, myOtherParam:"hello"});

当您需要传递大量参数时,它非常有用,IMO 它使使用函数比使用经典方法更容易。

myFunction(1,"hello");

C++中有类似的东西吗?

TIA

【问题讨论】:

  • 您应该澄清:您是否希望它是强类型的? IE。函数应该定义其参数的数量和类型还是您希望它由调用者定义?
  • 是的,该函数应该定义参数的类型和数量,但我应该能够不发送所有参数并分配默认值。

标签: c++


【解决方案1】:

boost 参数http://www.boost.org/doc/libs/release/libs/parameter/ 做你想做的事。

摘自其摘要:

使用这个库来编写函数和类模板,可以 按名称接受参数

小例子:

// include boost parameter
#include <boost/parameter/keyword.hpp>
namespace parameter = boost::parameter;

// first declare named parameters
BOOST_PARAMETER_NAME(a)      // Note: no semicolon
BOOST_PARAMETER_NAME(b)

// then declare your function
BOOST_PARAMETER_FUNCTION(
      (int),                 // 1. parenthesized return type
      my_function,           // 2. name of the function
      tag,                   // 3. namespace of tag types (don't change!)
      (required (a, int) )   // 4. one required parameter of type int
      (optional              //    and an optional parameters, with default value
        (b, int, 0)
      )
)
{
  return a + b;
}

// then you can call it with no named parameters
int result = my_function(1, 2);

// or with named parameters
int result = my_function(_a=1, _b=2);

// also with optional parameters omitted
int result = my_function(_a=3);

【讨论】:

    【解决方案2】:

    您可以使用“命名参数习语”: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.20

    这会让你的电话看起来像:

    f(1).myOtherParam("Hello")
    

    参见here 与 Boost 参数的比较。

    【讨论】:

    • 我会采用这种技术。它似乎更容易实现并且使用起来非常优雅。
    【解决方案3】:

    一个可以使用结构:

    struct foo {
       int a,b,c;
       float f;
    }
    

    可悲的是,您需要在某个地方定义它们,并且接收函数需要接受它们,您不能就地制作它们。

    归根结底,C++ 中没有任何语言工具可以模仿 JavaScript 的“习语”。这些东西存在于动态语言的本质中,而 C++ 则不是。

    【讨论】:

      【解决方案4】:

      是的。

      在 C++ 中,对象是类的实例。您可以创建一个包含所有可能参数的类,实例化它并用您的特定值填充它,然后将该实例传递给函数。

      您不能只传递任意对象而不是函数的参数,因为 C++ 没有命名参数 - 只有位置很重要,而某种散列结构中的位置会丢失。因此,当您有一个函数 foo(int x, int y) 时,您不能说 foo(y=3),因为名称 xy 仅在函数内有意义 - 对它的调用者没有意义。

      【讨论】:

        【解决方案5】:

        不,不是真的。标准库中有一个map 类,当然您可以编写一个函数来接受一个充满命名值的map 作为输入,但是没有什么可以直接作为与您所展示的语言功能等效的语言功能.

        正如其他几位发帖人所指出的那样,您当然可以定义一个类来保存所有数据值,但这只是将有序参数列表从函数推送到该对象的构造函数,所以它根本不会为您买任何东西.

        【讨论】:

          【解决方案6】:

          使用结构或类对数据进行分组。

          如果您正在寻找传递键值对的方法,请使用STL maps

          【讨论】:

            【解决方案7】:

            不是在语言层面,而是:

            当你有很多参数要传递时,它非常有用,IMO 它使使用函数比使用经典方法更容易。

            如果可以的话,你真的应该考虑减少你的参数。这通常可以通过使用聚合来实现:

            Example: 
                draw_rectangle(x1, y1, x2, y2, r, g, b, a)
            Could be reduced to:
                draw_rectangle(p1, p2, color)
            Or even further:
                draw_rectangle(rect, color)
            

            如果你这样做,命名参数的诱惑应该会大大减少。

            您还可以使用诸如 Boost Parameter 之类的替代方法,它通过大量的模板魔法来完成类似的事情。但是,它要求您将使用此技术的所有函数转换为以非常精确的方式编写的模板,并且如果您问我,这是一种非常庞大且笨拙的尝试来强制该语言做一些它原本不打算做的事情。

            【讨论】:

              【解决方案8】:

              您可以执行以下操作,它支持有限数量的默认值(受 C++ 模板系统的限制)。您需要使用最新标准 (C++11) 编译它

              // used to skip arguments and default to the previously specified value
              struct UseDefault {
                // empty intentionally!
              };
              
              // using this is optional, and only required if you want to provide default values by the CALLED function
              template <typename T, T def> struct Default {
                T value;
                operator T() {
                  return value;
                }
                Default(T value) : value(value) {}
                Default(UseDefault ignore) : value(def) {(void)ignore;}
              };
              
              // using tuple, you can bundle any number of parameters to one
              int myFunc(std::tuple<Default<int,7>,Default<char,'x'>,std::string> parameters) {
                std::cout << std::get<0>(parameters) << ", " << std::get<1>(parameters) << std::endl;
                return 0;
              }
              

              然后您可以像这样调用myFunc

              func(std::make_tuple(6,UseDefault(),"hi"));
              

              但是请注意,模板参数类型有一些限制,例如,您不能将字符串(或char*s)作为模板参数传递。但是,如果您只需要合理的基本默认值,这可能会起作用。

              当然,如果您放弃指定默认值的要求,您可以简单地使用 std::tuple 而无需我的 Default 类型。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2015-11-22
                • 2021-04-15
                • 1970-01-01
                • 2017-06-04
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-09-21
                相关资源
                最近更新 更多