给定 std::tuple<T...> 时可变参数模板类的实例化?
Instantiation of a variadic template class when given an std::tuple<T...>?
我正在尝试编写一个处理程序类,当给定元组时,它可以动态处理给定元组中的特定字段。
问题是,我不知道如何创建该类的实例,因为该类是模板化的,而我实例化所需的模板在元组内。
(由于与问题无关的设计请求,将处理程序放在单独的类中很重要)
请注意ILevelHandler
实例中的???
,我需要提供模板,但不确定该怎么做。
#include <tuple>
#include <string>
#include <iostream>
#include <boost/variant.hpp>
template <typename... T>
class ILevelHandler
{
public:
virtual void HandleEnterLevel(const boost::variant<T...>& _value)
{
std::cout << " value: " << _value << std::endl;
}
};
int main()
{
std::tuple<int, float, std::string, int> tpl {4, 6.6, "hello", 7};
ILevelHandler<???> lvl(tpl);
for (size_t i = 0; i < 4; ++ i)
{
lvl.HandleEnterLevel(i, dynamic_get(i, tpl));
}
return 0;
}
值得一提的是:使用未包装在类中的函数解决问题很容易,尽管我需要提供一个抽象类,以便用户必须自己实现该函数。
作为一种可能的解决方案,您可以使用支持假函数,如下所示:
#include <tuple>
#include <string>
template <typename... T>
class ILevelHandler {
public:
ILevelHandler(const std::tuple<T...> &) {}
};
template<typename... T>
auto f(const std::tuple<T...> &) -> ILevelHandler<T...>;
int main() {
std::tuple<int, float, std::string, int> tpl {4, 6.6, "hello", 7};
decltype(f(tpl)) lvl(tpl);
return 0;
}
请注意,您不需要定义函数f
,像上面示例中的简单声明就足够了。
您还可以使用几个using
声明来清理一些语句:
// ...
template<typename T>
using MyILevelHandler = decltype(f(std::declval<T>()));
// ...
int main() {
using MyTuple = std::tuple<int, float, std::string, int>;
MyTuple tpl {4, 6.6, "hello", 7};
MyILevelHandler<MyTuple> lvl(tpl);
return 0;
}
假设你已经写了dynamic_get
(比如如果你需要帮助),那么一个简单的转换类应该可以做到这一点:
#include <tuple>
#include <string>
#include <iostream>
#include <boost/variant.hpp>
template <typename... T>
class ILevelHandler
{
public:
void HandleEnterLevel(const boost::variant<T...>& _value)
{
std::cout << " value: " << _value << std::endl;
}
};
template<class Thing>
struct to_variant;
template<class...T>
struct to_variant<std::tuple<T...>>
{
using type = boost::variant<T...>;
};
template<class T> using to_variant_t = typename to_variant<T>::type;
int main()
{
std::tuple<int, float, std::string, int> tpl {4, 6.6, "hello", 7};
using tuple_type = decltype(tpl);
using variant_type = to_variant_t<tuple_type>;
ILevelHandler< variant_type > lvl;
for (size_t i = 0; i < 4; ++ i)
{
lvl.HandleEnterLevel(i, dynamic_get(i, tpl));
}
return 0;
}
相关文章:
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 如果模板参数是另一个模板的实例化,则键入特征测试
- 如何在模板函数中实例化其长度使用模板参数的数组
- 函数在可变参数模板的实例化期间不可见
- 实例化模板时,我是否必须显式显示参数包中的类型?
- 从模板参数包实例化的访问类实现
- C++ 可变参数模板实例化深度超过最大值 900
- 与参数匹配的友元模板函数实例化
- 有没有办法根据命令行参数定义数组大小?运行时与编译时实例化?
- 在编译时检查未实例化的类模板是否继承自其第一个模板参数
- 如何将包装作为模板参数实例化专用模板类
- 如何在 c++ 中使用枚举参数实例化对象
- 使用NULL参数实例化模板类
- 使用模板参数实例化模板类
- 使用bool非类型参数实例化类模板时出错
- 从类别上防止或阻止使用特定参数实例化对象
- 如何用不同的参数实例化类
- 模板是否为相同类型的参数实例化多次
- C++:根据一个参数实例化一个模板化的类
- 用Constructor参数实例化类对象和不带参数C++的*运算符之间的区别