【发布时间】:2009-07-20 20:06:25
【问题描述】:
这就是问题。
【问题讨论】:
-
你能告诉我们 C++ 程序员你用“C# 参数”做什么吗?
-
@JohannesSchaub-litb 这是params 关键字
这就是问题。
【问题讨论】:
是的。在标准 C++ 中,您可以使用 va_arg 和 ... 语法。见MSDN for details。
对于 C++/CLI,有一个快捷方式。
你这样做:
void TheMethod( String^ firstArgument, ... array<Object^>^ variableArgs );
【讨论】:
对于具有相同方便语法的非托管 C++,没有。
但 C++ 中的函数支持 variable argument lists。
基本上,您声明一个函数,最后一个参数是省略号 (...),并在函数体内使用 va_start()/va_arg() 调用来解析提供的参数列表。
这种机制不是类型安全的,调用者可以传递任何东西,所以你应该清楚地记录函数的公共接口以及你期望传入的内容。
有关托管 C++ 代码,请参阅 Reed 的 cmets。
【讨论】:
如今,借助现代 C++,您可以对可变参数函数使用现代类型安全实践。
如果所有参数都具有相同的类型,则使用可变参数模板或 std::initializer_list
使用可变参数模板,您可以使用递归来遍历可变参数列表。可变参数模板示例:
template<class T>
void MyFoo(T arg)
{
DoSomething(arg);
}
template<class T, class... R>
void MyFoo(T arg, R... rest)
{
DoSomething(arg);
// If "rest" only has one argument, it will call the above function
// Otherwise, it will call this function again, with the first argument
// from "rest" becoming "arg"
MyFoo(rest...);
}
int main()
{
MyFoo(2, 5.f, 'a');
}
这保证了如果 DoSomething 或您在递归调用 MyFoo 之前运行的任何其他代码对于您传递给函数 MyFoo 的每个参数的类型都具有重载,则将调用确切的重载。
使用 std::initializer_list,您可以使用简单的 foreach 循环来遍历参数
template<class T>
void MyFoo(std::initializer_list<T> args)
{
for(auto&& arg : args)
{
DoSomething(arg);
}
}
int main()
{
MyFoo({2, 4, 5, 8, 1, 0}); // All the arguments have to have the same type
}
【讨论】:
static_assert 和可变参数模板来制作您自己的灵活初始化列表。前任您可以在示例中将 std::is_base_of 与 T 上的 static_assert 结合使用,以确保所有类型都派生自某个基类。
boost 中有一个named parameters 库(如果我正确理解 C# 中的参数是什么)。它允许编写这样的函数:
int y = lib::f(_name = "bob", _index = 2);
无法说明是否涉及大量开销。
【讨论】: