首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >实现可变类型特征

实现可变类型特征
EN

Stack Overflow用户
提问于 2014-07-11 05:59:51
回答 2查看 3K关注 0票数 19

简介

我正在寻找一种模式,用于将C++类型的特征转换为与其对应的变量。如果使用methodology来解决这个问题,那么使用generative programming patterns来自动完成任务将是理想的选择。

示例

请执行以下操作:

代码语言:javascript
复制
std::is_same<T, U>::value; 

我想写一个像这样工作的特征:

代码语言:javascript
复制
std::are_same<T1, T2, T3, T4>::value; 

当前方法

实现are_same很简单;寻找一个通用的解决方案我们可以想出一个工具来实现通用量化的任何变量特征:

代码语言:javascript
复制
template<template<class,class> class F, typename...Ts>
struct Univ;

template<template<class, class> class F, typename T, typename U, typename...Ts>
struct Univ<F, T, U, Ts...>
{
    static const int value = F<T, U>::value && Univ<F, U, Ts...>::value;
};

template<template<class, class> class F, typename T>
struct Univ<F, T>
{
    static const int value = 1;
};

因此,例如are_same可以是

代码语言:javascript
复制
Univ<is_same,int, int, int>::value

在创建are_classesare_scalars等特征时,这一点也适用

泛化

细微的调整可能会给出存在量化,而不是之前的代码片段(用||替换&& ),这样我们就可以用下面的方式创建像exist_same这样的特征:

代码语言:javascript
复制
Exist<is_same, int, double, float>::value

问题

上一篇关于type traits的文章概括了

操作主要类型categories

  • Composite类型categories

  • Type properties

  • Supported

如何对如下类型特征进行泛化:

代码语言:javascript
复制
    enable_if -> enable_if_any // enable if any clause is true
                 enable_if_all // enalbe if all clauses are true
                 enable_for    // enable only for the type provided

上面的exist_same 示例过于简单。对正确的实现有什么想法吗?

有一些type_traits可以“返回”修改过的类型。对于将这些扩展到任意数量类型的实现,有什么建议吗?

有没有让type_traits 不能扩展到任意数量的类型参数的

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-11 06:12:49

我不完全理解您到底想实现什么,但以下帮助程序可能会很有用,从bool_sequence开始

代码语言:javascript
复制
#include <type_traits>

// Note: std::integer_sequence is C++14,
// but it's easy to use your own version (even stripped down)
// for the following purpose:
template< bool... Bs >
using bool_sequence = std::integer_sequence< bool, Bs... >;

// Alternatively, not using C++14:
template< bool... > struct bool_sequence {};

接下来,您可以检查所有或任何布尔值,或者使用以下内容进行设置:

代码语言:javascript
复制
template< bool... Bs >
using bool_and = std::is_same< bool_sequence< Bs... >,
                               bool_sequence< ( Bs || true )... > >;

template< bool... Bs >
using bool_or = std::integral_constant< bool, !bool_and< !Bs... >::value >;

它们可以作为更高级、更专业的特性的构建块而派上用场。例如,您可以这样使用它们:

代码语言:javascript
复制
typename< typename R, bool... Bs > // note: R first, no default :(
using enable_if_any = std::enable_if< bool_or< Bs... >::value, R >;

typename< typename R, bool... Bs > // note: R first, no default :(
using enable_if_all = std::enable_if< bool_and< Bs... >::value, R >;

typename< typename T, typename... Ts >
using are_same = bool_and< std::is_same< T, Ts >::value... >;
票数 24
EN

Stack Overflow用户

发布于 2016-07-08 23:47:47

您还可以使用std::conditional来实现enable_if_allenable_if_any

代码语言:javascript
复制
#include <type_traits>
#include <iostream>
#include <initializer_list>
#include <string>

namespace detail
{
template <typename... Conds>
struct and_ : std::true_type {};

template <typename... Conds>
struct or_ : std::false_type {};

template <typename Cond, typename... Conds>
struct and_<Cond, Conds...>
    : std::conditional<Cond::value, detail::and_<Conds...>, std::false_type>::type {};

template <typename Cond, typename... Conds>
struct or_<Cond, Conds...>
    : std::conditional<Cond::value, std::true_type, detail::and_<Conds...>>::type {};
}

template <typename... T>
using are_all_pod = detail::and_<std::is_pod<T>...>;

template <typename... T>
using any_is_pod = detail::or_<std::is_pod<T>...>;

template <typename... Args, typename = typename std::enable_if<are_all_pod<Args...>::value>::type>
void f(Args... args)
{
  (void)std::initializer_list<int>{(std::cout << args << '\n' , 0)...};
}

template <typename... Args, typename = typename std::enable_if<any_is_pod<Args...>::value>::type>
void g(Args... args)
{
  (void)std::initializer_list<int>{(std::cout << args << '\n' , 0)...};
}

int main()
{
  std::string s = "hello";  // non pod
  //f(1, 1.2, s); // this will fail because not all types are pod
  g(1, 1.2, s);   // this compiles because there is at least one pod in argument pack 
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24687026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档