【发布时间】:2017-07-19 12:23:16
【问题描述】:
为了更好地理解可变参数模板,我为自己设定了根据给定条件编写编译时类型选择器的任务(在<type_traits> 中定义的条件中选择,例如std::is_signed、std::is_floating_point 等。 )。选择器应在指定为模板参数的那些类型中选择满足条件的第一个类型。
举个例子:
template<template<typename> class Cond, typename... T>
struct first_if_any {
// some code here
};
first_if_any<std::is_signed, unsigned, long, int>::type a; // long
first_if_any<std::is_unsigned, short, unsigned long, unsigned>::type b; // unsigned long
first_if_any<std::is_floating_point, int, float, double>::type c; // float
这些是我希望我的选择器具有的功能:
- 如果没有类型满足条件,则选择第一种类型
- 如果未指定类型,则打印用户友好的编译错误
因此:
first_if_any<std::is_unsigned, long, int>::type a; // long
first_if_any<std::is_arithmetic>::type b; // ERROR
这是我想出的(参见工作示例here):
template<template<typename> class Cond, typename... T>
struct first_if_any {
using type = void;
static constexpr bool found = false;
};
template<template<typename> class Cond, typename First, typename... T>
struct first_if_any<Cond, First, T...> {
using type = typename std::conditional<Cond<First>::value || !first_if_any<Cond, T...>::found, First, typename first_if_any<Cond, T...>::type>::type;
static constexpr bool found = Cond<First>::value || first_if_any<Cond, T...>::found;
};
这会按预期选择类型,并满足要求 1。现在回答我的问题:
- 我怎样才能满足要求 2,即如果有人尝试使用选择器而不向其传递类型,则会生成用户友好的编译错误?
- 有没有更好的方法来做到这一点(仅使用标准库功能)?
额外问题,如果有人愿意详细说明:
- 这是否符合模板元编程的条件?
【问题讨论】:
-
使用
template<template<typename> class Cond, typename T, typename... Ts> struct first_if_any;,编译器会在使用时因缺少模板参数而产生错误,因为您至少需要一个,因此请用您的专业化替换您的基类。 -
@Jarod42: this 是什么意思?编译器抱怨:“类模板部分特化不特化任何模板参数”。
-
不完全一样,例如that。我还必须更改定义顺便说一句(和with error message)
-
您当前实现的问题是您想禁止
first_if_any<Cond>,但您使用它(first_if_any<Cond, T...>当T...为空时)。 -
@Jarod42:知道了。谢谢,这是很棒的东西。它足以回答我的两个问题,如果你愿意,可以发布一个。
标签: c++ c++11 templates variadic-templates typetraits