在可变参数模板函数中存储参数而不使用 boost::any
Storing arguments in a variadic template function without using boost::any
我用变量模板函数的 C++11 编写了以下短代码,并将参数存储到 boost::any 类型的向量中。它运行良好,但我不想使用 boost::any 库(由于某些限制(。
#include <boost/any.hpp>
template <class Var, class... Args>
void cpp_for(Var *variable, uint32_t numParams, Args... args)
{
std::vector<boost::any> arguments{args...};
if(arguments.size() != numParams)
throw std::runtime_error("mismatch");
for(uint32_t i = 0; i < numParams; ++i)
variable[i] = *(boost::unsafe_any_cast<Var>(&arguments[i]));
}
我像这样调用函数:
cpp_for(myObj->var, 3, 0x56, 0x23, 0x10);
或
cpp_for(myObj2->var, 2, myObj2->var2, myObj2->var3);
有没有办法存储参数并一一处理它们,而无需 boost::any?
编辑1:我的参数都是同一类型。
编辑2:由于上面代码的目标是assignment
,因此创建一个额外的数据结构(向量(是没有用的。查看"Nir Friedman"的答案,以获得更有效的解决方案。
您可以使用std::common_type
,例如:
template <class Var, class... Args>
void CPP_FOR(Var *variable, uint32_t numParams, Args... args)
{
std::vector<std::common_type_t<Args...>> arguments{args...};
// do stuff with arguments
}
您还可以删除numParams
和运行时检查,因为如果没有通用类型,这将在编译时失败。如果你只想迭代参数,向量可能是矫枉过正......所以像这样:
template <class Var, class... Args>
void CPP_FOR(Var *variable, Args... args)
{
std::common_type_t<Args...> arguments[]{args...};
for(size_t i = 0; i < sizeof...(Args); ++i)
variable[i] = /* ... */;
}
请注意,如果sizeof... (Args)
为 0,则这两种操作都将失败,即您只使用Var*
调用 - 如有必要,您可能需要单独处理这种情况。
假设你的目标实际上只是执行赋值,你根本不需要向量。
template <class Var, class... Args>
void CPP_FOR(Var *variable, uint32_t numParams, Args... args)
{
if(sizeof...(Args) != numParams)
throw std::runtime_error("mismatch");
int i = 0;
int temp [] = {(variable[i++] = args, 0)...};
}
现场示例:http://coliru.stacked-crooked.com/a/710a09332bf2c965
与创建难以优化的向量相比,这种开销不仅为零,而且还允许以最自然的方式进行隐式转换。其他方法可能会有惊喜。
如果你知道至少会有一个参数,你可以用稍微不同的方式编写你的函数来做到这一点。
template <typename Arg, typename... Args>
void cpp_for(Arg arg, Args... args) {
std::vector<Arg> vec { arg, args... };
// ...
}
但是,如果参数列表为空,这将失败。最简单的解决方案是简单地添加不需要参数的cpp_for
的第二个重载。
void cpp_for() {
std::vector<SomeDefaultType> vec; // Empty vector
// ...
}
当然,只有在使用零参数调用函数有意义时才需要这样做。
请记住,如果Args
和Arg
最终不是同一类型,则此方法将给出非常悲惨的错误消息。这可以通过一些 小心使用static_assert
.
- 泛化传递给 boost::bind 的参数
- boost::p rogram_options 在指定意外的位置参数时不报告任何错误
- 如何通过 boost::p ython 重命名构造函数的关键字参数
- 无法将参数传递给 boost::thread 构造函数
- 在 Windows 中使用 boost::p rogram_options 从命令行参数读取 Unicode 字符
- C++ Boost - 序列化错误 - 将"const B"作为"this"参数
- 如何正确地将 boost::optional<std::chrono::d uration> 作为函数参数?
- Boost::Asio串行读/写打开:参数不正确
- 使用单独的参数调用"boost::process::system()"时,获取"execv
- boost::asio::async_write无效参数
- 在可变参数模板函数中存储参数而不使用 boost::any
- 可变参数宏:重用可变参数(Boost.Fusion)
- boost::p rogram_options 验证每个参数而不是每个参数类型?
- 在 boost::<double>asio::buffer 中使用像 std::vector<std::complex> 这样的参数
- 将 std::bind 应用于带有参数 <boost::asio::ip::tcp::socket> 时出错?
- 如何创建一个版本的 boost::range::transform,该版本具有用于捕获上下文的额外参数
- 如何使用 boost::bind 附加参数?
- 是否可以使用 Boost.Hana 将 std::array 解压缩到非类型模板参数包中
- 参数从 Python 脚本传递到 C++ 使用 boost-python
- 当Boost ::绑定模板函数时,模板参数扣除/替换失败