我正试图使一些Java代码适应c++,它们在方法中使用可变参数。在他们的代码中,他们能够在for
循环中将参数作为列表进行迭代。在c++中有类似的行为吗?
我很难理解这个概念,我觉得我可能对这在c++中是如何实现的有一个根本性的误解。我在网上看到了一些类似的代码,似乎将参数列表转换为向量,我在下面尝试实现(注意,我需要一个指针向量,以便我可以调用accept()
方法的子对象实现)。
std::string AstPrinter::parenthesize(std::string name, Expr<std::string> exprs...)
{
std::vector<Expr<std::string>*> exprVec = { exprs... };
name = "(" + name;
for (Expr<std::string>* expr : exprVec)
{
name += " ";
name += expr->accept(this);
}
name += ")";
return name;
}
代码在第52行给出了这些错误:
no instance of constructor "std::vector<_Ty, _Alloc>::vector [with _Ty=Expr<std::string> *, _Alloc=std::allocator<Expr<std::string> *>]" matches the argument list
expected a }
cannot convert from 'initializer list' to 'std::vector<Expr<std::string> *,std::allocator<Expr<std::string> *>>'
并不一定要在向量中。我只是想知道如何访问参数列表的成员,以便我可以调用它们版本的accept()
方法。
有三种不同的方式来接受可变数量的参数。
首先,C风格变量。你可能不希望这样。
第二,c++可变模板。如果所有内容都是相同的类型,那么可能有点小题大做。最后,如果数据是const,则使用std::initializer_list
。否则,只是一个std::vector
.
std::string AstPrinter::parenthesize(std::string name, std::vector<Expr<std::string>> exprs)
在呼叫现场,执行printer.parenthesize("foo", {Expr0, Expr1, Expr2});
。注意额外的{}
。
这是解决你的问题最简单的方法。
在c++ 17及以后的版本中,如果使用折叠表达式,可以避免将可变参数复制到vector
中,例如:
template <typename... Args>
std::string AstPrinter::parenthesize(const std::string& name, const Args&... exprs)
{
return "("
+ name
+ (
(" " + exprs.accept(this)) + ... // <-- here
)
+ ")";
}
在线演示