为 type_traits class 创建一个 "negate" 包装器
Create a "negate" wrapper for a type_traits class
假设我有一个 Filter
元函数来过滤类型列表:
template<template<typename> class TFilter, typename... Ts>
using Filter = MetaList</* check TFilter<T>{}() for every type in Ts... */>;
元函数可以这样使用:
Filter<std::is_pod, int, char, std::string, int>
// ...returns...
MetaList<int, char, int>
现在,我想要获取所有不是 POD 的类型。我可以创建一个 FilterNot
元函数,但我实际上也需要其他元函数中的 "negation"。
是否可以为任何 type-trait-like 模板创建否定包装器 class?
所需代码:
Filter<Negate<std::is_pod>, int, char, std::string, int>
// ...returns...
MetaList<std::string>
一种方法:
#include <iostream>
#include <type_traits>
using namespace std;
template<template <class> class P>
struct invert
{
template<class... Args>
struct templ {
static constexpr bool value = ! P<Args...>::value;
};
};
int main()
{
cout << invert<is_pod>::templ<string>::value << endl;
cout << is_pod<string>::value << endl;
return 0;
}
template<template<class...>class Z>
struct negate {
template<class...Ts>
using result=std::integral_constant<bool, !Z<Ts...>::value>;
};
Filter<negate<std::is_pod>:: template result, int, char, std::string, int>;
或
Filter<typename negate<std::is_pod>::result, int, char, std::string, int>;
取决于编译器应该工作。 (IIRC,一些编译器对此很古怪)
我觉得这个语法很别扭,也许可以列出菊花链测试?那么否定只是堆栈上的另一个特征:
template<template<class...>class... Zs>
struct tests {};
然后取 tests
并递归应用 Zs
。
template<class B>
using negate=std::integral_constant<bool,!B::value>;
filters<tests<negate, std::is_pod>, int, std::string>
另一种方法是进行测试并使它们在 tag<type>{}
上使用 constexpr 函数(很容易做到),这在语法上更容易编写。从 template<class>class
到 constexpr bool(tag<class>)
并不难。
假设我有一个 Filter
元函数来过滤类型列表:
template<template<typename> class TFilter, typename... Ts>
using Filter = MetaList</* check TFilter<T>{}() for every type in Ts... */>;
元函数可以这样使用:
Filter<std::is_pod, int, char, std::string, int>
// ...returns...
MetaList<int, char, int>
现在,我想要获取所有不是 POD 的类型。我可以创建一个 FilterNot
元函数,但我实际上也需要其他元函数中的 "negation"。
是否可以为任何 type-trait-like 模板创建否定包装器 class?
所需代码:
Filter<Negate<std::is_pod>, int, char, std::string, int>
// ...returns...
MetaList<std::string>
一种方法:
#include <iostream>
#include <type_traits>
using namespace std;
template<template <class> class P>
struct invert
{
template<class... Args>
struct templ {
static constexpr bool value = ! P<Args...>::value;
};
};
int main()
{
cout << invert<is_pod>::templ<string>::value << endl;
cout << is_pod<string>::value << endl;
return 0;
}
template<template<class...>class Z>
struct negate {
template<class...Ts>
using result=std::integral_constant<bool, !Z<Ts...>::value>;
};
Filter<negate<std::is_pod>:: template result, int, char, std::string, int>;
或
Filter<typename negate<std::is_pod>::result, int, char, std::string, int>;
取决于编译器应该工作。 (IIRC,一些编译器对此很古怪)
我觉得这个语法很别扭,也许可以列出菊花链测试?那么否定只是堆栈上的另一个特征:
template<template<class...>class... Zs>
struct tests {};
然后取 tests
并递归应用 Zs
。
template<class B>
using negate=std::integral_constant<bool,!B::value>;
filters<tests<negate, std::is_pod>, int, std::string>
另一种方法是进行测试并使它们在 tag<type>{}
上使用 constexpr 函数(很容易做到),这在语法上更容易编写。从 template<class>class
到 constexpr bool(tag<class>)
并不难。