组合类模板默认参数和变异参数
Combine class template default parameters and variadic parameters
我正在设计一个使用固定数量的Policies
类的Host
类,大约3或4。
因为对于设计中的每个Policy
,总会有一个微不足道的实现,因此默认模板参数为琐碎类型是很不错的,以便通过其客户端轻松使用Host
类。
class IdiotBenchPolicy {};
class IdiotLoggerPolicy {};
// ...
template <typename BenchmarkPolicy = IdiotBenchPolicy,
typename LoggerPolicy = IdiotLoggerPolicy>
class Host
{
BenchmarkPolicy m_bench;
IdiotLoggerPolicy m_logger;
};
这允许实例化Host
,而无需指定长列表的模板参数。
这是可以的,直到Host
类还必须采用可变数量的算术类型。当解决问题并忘记Policies
时,我能够使用variadic模板参数:
template <class... Args>
class Host
{
template <class ...Var_Args>
using are_arithmetic = typename std::conjunction<std::is_arithmetic<Var_Args>...>::type;
static_assert(are_arithmetic<Args...>::value, "Args are not all arithmetic type");
std::tuple<Args...> m_args;
};
请注意,即使Host
在内部使用元组,最好不要在类客户上执行它。
我现在的问题是结合两种行为。如果"默认值"足够,如何实例化Host
类而无需指定Policies
。我不确定如何使用C 模板语法表达这一点,但是我的直觉告诉我,与Sfinae和std and std :: enable_if杂耍是可能的,但是我很难看到如何。
我想写的是:
Host<int, int, float> h; //Using both default policies
Host<SmarterBenchPolicy, float, double> h2; //Using SmarterBenchPolicy, IdiotLoggerPolicy and two arithmetic types
Host<SmarterBenchPolicy>; //Using SmarterBenchPolicy, IdiotLoggerPolicy and no arithmetic type
将如何使用类似于上述的实例来构造的Host
类是如何实现的?
我认为,如果您将这些参数放在参数列表和默认值的参数会更好。variadic参数可以包装到std::tuple
中:
template <class ArgsPack,
typename BenchmarkPolicy = IdiotBenchPolicy,
typename LoggerPolicy = IdiotLoggerPolicy,
std::enable_if_t<detail::is_tuple<ArgsPack>::value, int> = 0
>
struct Host
{
BenchmarkPolicy bench;
LoggerPolicy logger;
ArgsPack args;
void show_all() {
detail::tuple_foreach([](const auto &e) {std::cout << e << "n";}, args);
}
};
Host<std::tuple<int, int, float>, SmartBenchPolicy> h;
这是一种方法。它必须将其扩展到两个策略参数。
#include <iostream>
#include <type_traits>
#include <tuple>
struct BenchPolicyBase {
};
struct BenchPolicy1 : BenchPolicyBase {
};
template <class enabler, class... Args>
class HostClass
{
//Use default policy
public:
HostClass() { std::cout << "default" << std::endl; }
template <class ...Var_Args>
using are_arithmetic = typename std::conjunction<std::is_arithmetic<Var_Args>...>::type;
static_assert(are_arithmetic<Args...>::value, "Args are not all arithmetic type");
std::tuple<Args...> m_args;
BenchPolicyBase m_bench;
};
template <typename T, typename... Rest>
using Host = HostClass<void, T, Rest...>;
template <class BenchPolicy, class... Args>
class HostClass<std::enable_if_t<std::is_base_of<BenchPolicyBase, BenchPolicy>::value>, BenchPolicy, Args...>
{
//Use BenchPolicy
public:
HostClass() { std::cout << "Bench" << std::endl; }
template <class ...Var_Args>
using are_arithmetic = typename std::conjunction<std::is_arithmetic<Var_Args>...>::type;
static_assert(are_arithmetic<Args...>::value, "Args are not all arithmetic type");
std::tuple<Args...> m_args;
BenchPolicy m_bench;
};
int main() {
Host<int, long> a;
Host<BenchPolicy1, int, long> b;
return 0;
}
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 具有变异模板模板参数的方法的部分专业化
- 我如何实现变异模式以将可变数量的参数转发到C 11中的函数
- 组合类模板默认参数和变异参数
- 继承具有变异参数的构造函数
- C 参数包作为变异模板
- 在没有参数的变异模板中迭代
- 结构化参数为变异模板
- C 是否允许在变异模板参数之后进行普通参数
- 计数宏函数中变异参数的数量
- 如何使模板通过变异参数推断返回类型的函数
- 为什么C 不允许在非模板函数中进行变异参数
- C :处理Visual Studio中的每个变异参数
- 为什么这个嵌套的变异模板是无效的参数
- 如何绑定变异模板参数与功能