给定 std::tuple<T...> 时可变参数模板 class 的实例化?
Instantiation of a variadic template class when given an std::tuple<T...>?
我正在尝试编写一个处理程序 class,当给定一个元组时,它可以动态处理给定元组中的特定字段。
问题是,我不知道如何创建 class 的实例,因为 class 是模板化的,而实例化所需的模板在元组中。
(由于与问题无关的设计要求,将处理程序放在单独的 class 中很重要)
请注意 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;
}
重要提示:使用未包含在 class 中的函数解决问题很容易,但我需要提供一个摘要 class,以便用户必须自己实现功能。
假设您已经编写了 dynamic_get
(如果您需要帮助),那么一个简单的转换 class 应该可以做到:
#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;
}
作为一种可能的解决方案,您可以使用如下所示的支持假函数:
#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;
}
我正在尝试编写一个处理程序 class,当给定一个元组时,它可以动态处理给定元组中的特定字段。
问题是,我不知道如何创建 class 的实例,因为 class 是模板化的,而实例化所需的模板在元组中。
(由于与问题无关的设计要求,将处理程序放在单独的 class 中很重要)
请注意 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;
}
重要提示:使用未包含在 class 中的函数解决问题很容易,但我需要提供一个摘要 class,以便用户必须自己实现功能。
假设您已经编写了 dynamic_get
(如果您需要帮助),那么一个简单的转换 class 应该可以做到:
#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;
}
作为一种可能的解决方案,您可以使用如下所示的支持假函数:
#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;
}