像 c++ 中的 c# 参数一样吗?
Posted
技术标签:
【中文标题】像 c++ 中的 c# 参数一样吗?【英文标题】:Anything like the c# params in c++? 【发布时间】:2009-07-20 20:06:25 【问题描述】:这就是问题。
【问题讨论】:
你能告诉我们 C++ 程序员你用“C# 参数”做什么吗? @JohannesSchaub-litb 这是params 关键字 【参考方案1】:是的。在标准 C++ 中,您可以使用 va_arg 和 ... 语法。见MSDN for details。
对于 C++/CLI,有一个快捷方式。
你这样做:
void TheMethod( String^ firstArgument, ... array<Object^>^ variableArgs );
看到这个blog post for details。
【讨论】:
很高兴知道...不知道 C++ 有这个托管代码扩展。 @LBushkin:更新到更好的语法。【参考方案2】:对于具有相同方便语法的非托管 C++,没有。
但 C++ 中的函数支持 variable argument lists。
基本上,您声明一个函数,最后一个参数是省略号 (...),并在函数体内使用 va_start()/va_arg() 调用来解析提供的参数列表。
这种机制不是类型安全的,调用者可以传递任何东西,所以你应该清楚地记录函数的公共接口以及你期望传入的内容。
有关托管 C++ 代码,请参阅 Reed 的 cmets。
【讨论】:
【参考方案3】:如今,借助现代 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 结合使用,以确保所有类型都派生自某个基类。【参考方案4】:
boost 中有一个named parameters 库(如果我正确理解 C# 中的参数是什么)。它允许编写这样的函数:
int y = lib::f(_name = "bob", _index = 2);
无法说明是否涉及大量开销。
【讨论】:
C# 参数未命名为参数 - 它是可变长度参数列表。以上是关于像 c++ 中的 c# 参数一样吗?的主要内容,如果未能解决你的问题,请参考以下文章
我可以像在 c++ 中使用指针一样修改函数中的变量而不在 python 中返回吗
C# 是像 Objective-C 和 C++ 一样的 C 超集吗?
有没有办法像在 C++ 中挂钩非托管函数一样在 C# 中挂钩托管函数?