使用参数向量在 C++ 中调用可变参数函数
Call variadic function in C++ with a vector of arguments
假设我有一个像这样的可变函数:
template <typename... A>
void func(A... args)
{
//Do stuff
}
我也有这样的矢量:
enum Type{
DOUBLE,
STRING
};
std::vector<std::pair<std::string, Type>> varg;
所以我想迭代地图的元素并调用具有指定类型的模板函数,例如:varg = {{"a", Type::STRING}, {"1.2", Type::DOUBLE}};
应该打电话给 func("a", 1.2)
关于如何做到这一点的任何提示?
您在这里混淆了 compile-time 和运行时功能。 (提示:这是行不通的)
作为 thought-experiment:
假设您有某种类型的 std::vector<>
,其中填充了一些数据,例如 N
条目。请注意,此 N
是先验的 只有 在运行时已知!
现在您想将这些 N
数据段解压缩到一个可变参数模板中,必须 完成 compile-time 的事情!模板是 compile-time 功能!
这行不通。如果您使用 compile-time 容器(参见 boost::mpl
),原则上您可以做类似的事情。但是这些要求您知道(或可以计算)compile-time.
处的所有内容
另外,您可能想看看 boost::fusion
是如何尝试弥合这一差距的。尽管您应该始终注意它不能!模板仍然只有 compile-time。
在最低级别 (C-like),application binary interface follows some calling conventions,特别是参数如何传递给函数,它通常取决于参数的类型(通常,指针进入某些处理器寄存器和浮点数放在其他类型的寄存器中)。
如果你想调用一个未知签名的函数(即你只在运行时知道它的签名和实际参数及其数量,而不是在编译时)你需要一些ABI 特定的技巧,可能还有一些机器特定的代码。您可以考虑使用提供
的 libffi
a portable, high level programming interface to various calling conventions
顺便说一句,您可以考虑将您的值打包或装入某些 "universal" 容器中 boost::any or QVariant or your own tagged unions, or perhaps boost::variant
也许您可能想在您的应用程序中嵌入一些解释器,例如GNU guile or Lua.
请注意,对于 C 或 C++,函数和函数指针有一些 compile-time 已知签名,这很重要。调用带有错误签名的东西(即签名不是编译器期望的函数)是 undefined behavior.
假设我有一个像这样的可变函数:
template <typename... A>
void func(A... args)
{
//Do stuff
}
我也有这样的矢量:
enum Type{
DOUBLE,
STRING
};
std::vector<std::pair<std::string, Type>> varg;
所以我想迭代地图的元素并调用具有指定类型的模板函数,例如:varg = {{"a", Type::STRING}, {"1.2", Type::DOUBLE}};
应该打电话给 func("a", 1.2)
关于如何做到这一点的任何提示?
您在这里混淆了 compile-time 和运行时功能。 (提示:这是行不通的)
作为 thought-experiment:
假设您有某种类型的 std::vector<>
,其中填充了一些数据,例如 N
条目。请注意,此 N
是先验的 只有 在运行时已知!
现在您想将这些 N
数据段解压缩到一个可变参数模板中,必须 完成 compile-time 的事情!模板是 compile-time 功能!
这行不通。如果您使用 compile-time 容器(参见 boost::mpl
),原则上您可以做类似的事情。但是这些要求您知道(或可以计算)compile-time.
处的所有内容
另外,您可能想看看 boost::fusion
是如何尝试弥合这一差距的。尽管您应该始终注意它不能!模板仍然只有 compile-time。
在最低级别 (C-like),application binary interface follows some calling conventions,特别是参数如何传递给函数,它通常取决于参数的类型(通常,指针进入某些处理器寄存器和浮点数放在其他类型的寄存器中)。
如果你想调用一个未知签名的函数(即你只在运行时知道它的签名和实际参数及其数量,而不是在编译时)你需要一些ABI 特定的技巧,可能还有一些机器特定的代码。您可以考虑使用提供
的 libffia portable, high level programming interface to various calling conventions
顺便说一句,您可以考虑将您的值打包或装入某些 "universal" 容器中 boost::any or QVariant or your own tagged unions, or perhaps boost::variant
也许您可能想在您的应用程序中嵌入一些解释器,例如GNU guile or Lua.
请注意,对于 C 或 C++,函数和函数指针有一些 compile-time 已知签名,这很重要。调用带有错误签名的东西(即签名不是编译器期望的函数)是 undefined behavior.