如何将可变参数模板参数的特征值减少为一个值?
How to reduce Trait-values of variadic template parameter to one value?
在试验可变参数模板时,我发现通过某种操作将特征值减少到一个最终值会很有用。我的用例是:
constexpr bool and(bool lhs, bool rhs){return lhs && rhs;}
struct Foo
{
template<
typename ...Ts>
Foo(
Ts&&... args)
noexcept(TraitReduction<std::is_nothrow_move_constructible, and, Ts...>::value)
{/*...*/}
}
问题在于 STL 特征都是单一模板类型。
我目前的工作解决方案是:
template<
template<typename> class TraitT,
bool (*Operator)(bool,bool),
typename T1,
typename ...Ts>
struct TraitReduction
{
static bool const value = TraitT<T1>::value;
};
template<
template<typename> class TraitT,
bool (*Operator)(bool,bool),
typename T1,
typename T2,
typename ...Ts>
struct TraitReduction<
TraitT,
Operator,
T1,
T2,
Ts...>
{
static bool const value = (*Operator)(
TraitT<T1>::value,
TraitReduction<TraitT, Operator, T2, Ts...>::value);
};
我的问题是,STL 是否为该任务提供了一些标准化(可能更方便)的解决方案?当然,我很乐意在这里对我当前的解决方案发表一些评论,哪些是不好的,哪些可以更好。
你的解决方案在实例化方面是线性的(并且没有短路的优势)
你可以在更少的实例化中做到这一点(并且仍然没有短路)
template <bool...> struct bools{};
template <template <typename> Trait, typename ... Ts>
struct all_of : std::is_same<bools<true, Trait<Ts>::value...>,
bools<Trait<Ts>::value..., true>> {};
你可以使用std::conjunction
,它是线性的,但有短路。
c++17 和折叠表达式有很好的语法,实例化较少(但没有短路(用于实例化)):
(Trait<Ts>::value && ...)
在试验可变参数模板时,我发现通过某种操作将特征值减少到一个最终值会很有用。我的用例是:
constexpr bool and(bool lhs, bool rhs){return lhs && rhs;}
struct Foo
{
template<
typename ...Ts>
Foo(
Ts&&... args)
noexcept(TraitReduction<std::is_nothrow_move_constructible, and, Ts...>::value)
{/*...*/}
}
问题在于 STL 特征都是单一模板类型。 我目前的工作解决方案是:
template<
template<typename> class TraitT,
bool (*Operator)(bool,bool),
typename T1,
typename ...Ts>
struct TraitReduction
{
static bool const value = TraitT<T1>::value;
};
template<
template<typename> class TraitT,
bool (*Operator)(bool,bool),
typename T1,
typename T2,
typename ...Ts>
struct TraitReduction<
TraitT,
Operator,
T1,
T2,
Ts...>
{
static bool const value = (*Operator)(
TraitT<T1>::value,
TraitReduction<TraitT, Operator, T2, Ts...>::value);
};
我的问题是,STL 是否为该任务提供了一些标准化(可能更方便)的解决方案?当然,我很乐意在这里对我当前的解决方案发表一些评论,哪些是不好的,哪些可以更好。
你的解决方案在实例化方面是线性的(并且没有短路的优势)
你可以在更少的实例化中做到这一点(并且仍然没有短路)
template <bool...> struct bools{};
template <template <typename> Trait, typename ... Ts>
struct all_of : std::is_same<bools<true, Trait<Ts>::value...>,
bools<Trait<Ts>::value..., true>> {};
你可以使用std::conjunction
,它是线性的,但有短路。
c++17 和折叠表达式有很好的语法,实例化较少(但没有短路(用于实例化)):
(Trait<Ts>::value && ...)