Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 创建对满足特定谓词的对象的引用元组_C++_C++11_C++14_Template Meta Programming_C++17 - Fatal编程技术网

C++ 创建对满足特定谓词的对象的引用元组

C++ 创建对满足特定谓词的对象的引用元组,c++,c++11,c++14,template-meta-programming,c++17,C++,C++11,C++14,Template Meta Programming,C++17,假设我们有以下三个结构 struct T1 { using type = std::tuple<A1, A2, A3>; } struct T2 { using type = std::tuple<A1, A2>; } struct T3 { using type = std::tuple<A1>; } struct T1 { 使用type=std::tuple; } 结构T2 { 使用type=std::tuple; } 结构T

假设我们有以下三个结构

struct T1
{
    using type = std::tuple<A1, A2, A3>;
}

struct T2
{
    using type = std::tuple<A1, A2>;
}

struct T3
{
    using type = std::tuple<A1>;
}
struct T1
{
使用type=std::tuple;
}
结构T2
{
使用type=std::tuple;
}
结构T3
{
使用type=std::tuple;
}
然后创建一个元组,其中包含以下类型的实例:

std::tuple<T1, T2, T3> types;
std::元组类型;
现在是棘手的部分-我如何创建这样的元组

std::tuple<std::tuple<T1&, T2&, T3&>, std::tuple<T1&, T2&>, std::tuple<T1&>>
std::tuple
在“类型”元组之外,其中

1) 。。。第一个元组包含对嵌套typedefs包含A1的所有元素的引用

2) 。。。第二个元组包含对嵌套typedefs包含A2的所有元素的引用

3) 。。。第三个元组包含对嵌套typedefs包含的所有元素的引用


编辑 我举了一个小例子来说明我正在尝试做什么,请记住这段代码还不起作用,但它应该能让您更好地理解我正在尝试做什么

#include <iostream>
#include <tuple>
#include <type_traits>
#include <utility>

namespace util
{
    template<typename Function, typename Tuple>
    void for_each(Function&& function, Tuple&& tuple) 
    { 
        std::apply([&function](auto&&... xs){ (function(std::forward<decltype(xs)>(xs)), ...); }, std::forward<Tuple>(tuple)); 
    } 
}

namespace tl
{
    template<typename T, typename Tuple>
    struct tuple_contains;

    template<typename T, typename Tuple, typename = std::make_index_sequence<std::tuple_size_v<Tuple>>>
    struct tuple_index;


    template<typename T, typename ...Ts>
    struct tuple_contains<T, std::tuple<Ts...>>
        : std::bool_constant<(std::is_same_v<T, Ts> || ...)>
    {};

    template<typename T, typename ...Ts, std::size_t ...Is>
    struct tuple_index<T, std::tuple<Ts...>, std::index_sequence<Is...>>
        : std::integral_constant<std::size_t, ((static_cast<std::size_t>(std::is_same_v<T, Ts>) * Is) + ...)>
    {};

    template<typename T, typename Tuple>
    inline constexpr auto tuple_contains_v{ tuple_contains<T, Tuple>::value };

    template<typename T, typename Tuple>
    inline constexpr auto tuple_index_v{ tuple_index<T, Tuple>::value };  
}

template<typename EventList>
class ObserverInterface;

template<typename ObserverList>
class ObserverManager;

template<typename EventList, typename ObserverList>
class EventManager;


template<typename T>
class EventHandler
{
public:
    virtual void Receive(const T&) = 0;
};

template<typename ...Events>
class ObserverInterface<std::tuple<Events...>>
    : public EventHandler<Events>...
{};

template<typename ...Observers>
class ObserverManager<std::tuple<Observers...>>
{
public:
    template<typename T>
    T& GetObserver() noexcept
    {
        return std::get<T>(observers_);
    }

private:
    std::tuple<Observers...> observers_;
};

template<typename ...Events, typename ...Observers>
class EventManager<std::tuple<Events...>, std::tuple<Observers...>>
{
public:
    EventManager(ObserverManager<std::tuple<Observers...>>& observerManager)
        : observerManager_{ observerManager }
    {}

public:
    template<typename T>
    static constexpr bool isEvent{ tl::tuple_contains_v<T, std::tuple<Events...>> };

    template<typename T>
    static constexpr std::enable_if_t<isEvent<T>, std::size_t> eventIndex{ tl::tuple_index_v<T, std::tuple<Events...>> };


public:
    template<typename T, typename ...Arguments>
    std::enable_if_t<isEvent<T>> DispatchEvent(Arguments&&... arguments) noexcept
    {
        T event(std::forward<Arguments>(arguments)...);

        util::for_each([&](auto&& observer){ observer.Receive(event); }, std::get<eventIndex<T>>(observers_)); 
    }

private:
    ObserverManager<std::tuple<Observers...>>& observerManager_;

    std::tuple</*     */> observers_;
};

struct EventOne
{
    float value;
};

struct EventTwo
{
    float value;
};

struct EventThree
{
    float value;
};

class ObserverOne final
    : public ObserverInterface<std::tuple<EventOne, EventTwo>>
{
public:

    using Events = std::tuple<EventOne, EventTwo>;

    void Receive(const EventOne& event) override
    {
        std::cout << "Received EventOne!\n";
    }

    void Receive(const EventTwo& event) override
    {
        std::cout << "Received EventTwo!\n";
    }
};

class ObserverTwo final
    : public ObserverInterface<std::tuple<EventTwo, EventThree>>
{
public:

    using Events = std::tuple<EventTwo, EventThree>;

    void Receive(const EventTwo& event) override
    {
        std::cout << "Received EventTwo!\n";
    }

    void Receive(const EventThree& event) override
    {
        std::cout << "Received EventThree!\n";
    }
};

using MainEventList = std::tuple<EventOne, EventTwo, EventThree>;
using MainObserverList = std::tuple<ObserverOne, ObserverTwo>;

int main()
{
    ObserverManager<MainObserverList> om;
    EventManager<MainEventList, MainObserverList> em(om);

    em.DispatchEvent<EventTwo>(10.f);

    return 0;
}
#包括
#包括
#包括
#包括
命名空间util
{
模板
每个(函数和函数、元组和元组)的void
{ 
std::apply([&函数](auto&&…xs){(函数(std::forward(xs)),…);},std::forward(tuple));
} 
}
名称空间tl
{
模板
结构元组包含;
模板
结构元组索引;
模板
结构元组包含
:std::bool_常数
{};
模板
结构元组索引
:std::积分常数
{};
模板
内联constexpr auto tuple_contains_v{tuple_contains::value};
模板
内联constexpr auto tuple_index_v{tuple_index::value};
}
模板
类observer接口;
模板
班级管理者;
模板
班级活动经理;
模板
类事件处理程序
{
公众:
虚空接收(常数T&)=0;
};
模板
类observer接口
:公共事件处理程序。。。
{};
模板
类观察者管理器
{
公众:
模板
T&GetObserver()不例外
{
返回std::get(观察员);
}
私人:
std::tuple;
};
模板
类事件管理器
{
公众:
事件管理器(ObserverManager和ObserverManager)
:observerManager{observerManager}
{}
公众:
模板
静态constexpr bool isEvent{tl::tuple_contains_v};
模板
静态constexpr std::enable_if_t eventIndex{tl::tuple_index_v};
公众:
模板
std::如果DispatchEvent(参数&&…参数)不例外,则启用
{
T事件(标准::转发(参数)…);
util::for_each([&](auto&&observer){observer.Receive(event);},std::get(obsers_));
}
私人:
ObserverManager和ObserverManager;
std::tuple;
};
结构事件
{
浮动值;
};
结构事件二
{
浮动值;
};
结构事件三
{
浮动值;
};
课堂观察者一个决赛
:公共观察者接口
{
公众:
使用Events=std::tuple;
无效接收(const EventOne和event)覆盖
{
std::cout
模板
使用type\u t=typename标签::type;
模板结构标记{using type=t;constexpr标记{};
模板constexpr tag_t tag{};
模板
结构fmap_元组{};
模板
使用fmap\u tuple\u t=类型\u t;
模板
结构fmap_元组:
标签
{};
模板
结构模板{
模板
使用结果=fmap\u tuple\t;
};
模板
使用cat_tuples=decltype(std::tuple_cat(std::declval()…);
模板
结构过滤器;
模板
使用过滤器\u t=类型\u t;
模板
结构过滤器:tag_t{};
模板
结构过滤器:
标签<
猫元组<
std::tuple,
过滤器
>
>
{};
模板
结构过滤器>:
滤波器
{};
模板
结构cat_Zs{
私人:
模板
使用Zs_result=typename cat_Zs::template result;
公众:
模板
使用结果=Z0;
};
模板
结构cat_Zs{
模板使用结果=Z0;
};
模板
结构是{
模板
使用结果=标准::是相同的;
};
模板
结构所有内容\u未通过\u测试{
模板
使用result=std::is_same;
};
模板
结构已通过测试{
模板
使用结果=标准::积分常数;
};
模板
使用loaks_T=一切都失败了_test;
模板
使用contains_T=has_test_passer;
模板
结构制造;
模板
使用make_kv_t=类型;
模板
结构制造:标签<
std::tuple
>{};
模板
结构获取;
模板
使用get_k_t=type_t;
模板
结构get_k:tag_t{};
模板
结构获取;
模板
使用get_v_t=type_t;
模板
结构get_v:tag_t{};
模板
使用步骤1=make_kv_t;
模板
使用值_has_T=cat_Zs;
模板
使用步骤2=过滤器<
值\u具有\u T::模板结果
,步骤1<元组>
>;
模板
使用step3=fmap\u tuple\t<
得到k__t,
步骤二
>;
模板
使用solution_base=std::tuple<
fmap_tuple_t<
标准::添加左值参考值,
步骤三
>...
>;
结构A1{};
结构A2{};
结构A3{};
模板
使用溶液=溶液\基础;
结构T1
{
使用type=std::tuple

这里我们定义了一些原语--
fmap\u tuple\u t
filter\u t
fmapper
cat\u tuples
cat\u Zs
拥有测试通行证
make\u kv\u t
get\u v\u t


然后,我们用这些原语构建一个类型表达式。

这是一个奇怪的特定请求。也是一个非常不特定的请求(tuple
转换成什么?tuple
转换成什么?
tuple
tuple
?a是如何发挥作用的?)。您尝试过什么?将
std::tuple
转换为
std::tuple
似乎很容易。将
std::tuple
转换为
std::tuple
似乎也很容易。这是一个痛苦的过程。但是,如果有一个调试过的TMP库,请将
tuple
映射到
tuple
,将
tuple
映射到
tuple
,筛选
tuple
通过
Pred
,将
tuple
映射到
tup
template<class Tag>
using type_t = typename Tag::type;
template<class T> struct tag_t{using type=T; constexpr tag_t(){}};
template<class T> constexpr tag_t<T> tag{};

template<template<class...>class Z, class Tuple>
struct fmap_tuple {};
template<template<class...>class Z, class Tuple>
using fmap_tuple_t = type_t<fmap_tuple<Z,Tuple>>;

template<template<class...>class Z, class...Ts>
struct fmap_tuple<Z, std::tuple<Ts...>>:
    tag_t<std::tuple<Z<Ts>...>>
{};

template<template<class...>class Z>
struct fmapper {
  template<class Tuple>
  using result=fmap_tuple_t<Z, Tuple>;
};

template<class...Tuples>
using cat_tuples = decltype(std::tuple_cat( std::declval<Tuples>()... ));

template<template<class...>class Z, class Tuple, class=void>
struct filter;
template<template<class...>class Z, class Tuple>
using filter_t = type_t<filter<Z,Tuple>>;

template<template<class...>class Z>
struct filter<Z, std::tuple<>,void>:tag_t<std::tuple<>>{};
template<template<class...>class Z, class T0, class...Ts>
struct filter<Z, std::tuple<T0, Ts...>, std::enable_if_t<Z<T0>::value>>:
    tag_t<
        cat_tuples<
            std::tuple<T0>,
            filter_t<Z, std::tuple<Ts...>>
        >
    >
{};
template<template<class...>class Z, class T0, class...Ts>
struct filter<Z, std::tuple<T0, Ts...>, std::enable_if_t<!Z<T0>::value>>:
    filter<Z, std::tuple<Ts...>>
{};

template<template<class...>class Z0, template<class...>class...Zs>
struct cat_Zs {
private:
    template<class...Ts>
    using Zs_result = typename cat_Zs<Zs...>::template result<Ts...>;
public:
    template<class...Ts>
    using result= Z0<Zs_result<Ts...>>;
};

template<template<class...>class Z0>
struct cat_Zs<Z0> {
    template<class...Ts> using result=Z0<Ts...>;
};

template<class T>
struct is_T {
    template<class U>
    using result = std::is_same<T,U>;
};

template<template<class...>class Test>
struct everything_fails_test {
    template<class Tuple>
    using result = std::is_same< std::tuple<>, filter_t<Test, Tuple> >;
};
template<template<class...>class Test>
struct has_test_passer {
    template<class Tuple>
    using result = std::integral_constant<bool,
        !everything_fails_test<Test>::template result<Tuple>::value
    >;
};

template<class T>
using lacks_T = everything_fails_test< is_T<T>::template result >;
template<class T>
using contains_T = has_test_passer< is_T<T>::template result >;


template<template<class...>class Z, class Tuple>
struct make_kv;
template<template<class...>class Z, class Tuple>
using make_kv_t = type_t<make_kv<Z,Tuple>>;

template<template<class...>class Z, class...Ts>
struct make_kv<Z,std::tuple<Ts...>>:tag_t<
    std::tuple< std::tuple<Ts, Z<Ts>>... >
>{};

template<class Tuple>
struct get_k;
template<class Tuple>
using get_k_t=type_t<get_k<Tuple>>;
template<class K, class V>
struct get_k<std::tuple<K,V>>:tag_t<K>{};
template<class Tuple>
struct get_v;
template<class...Tuple>
using get_v_t=type_t<get_v<Tuple...>>;
template<class K, class V>
struct get_v<std::tuple<K,V>>:tag_t<V>{};

template<class Tuple>
using step1 =  make_kv_t< type_t, Tuple >;

template<class T>
using value_has_T = cat_Zs<contains_T<T>::template result,get_v_t>;

template<class Tuple, class T>
using step2 = filter_t<
      value_has_T<T>::template result
    ,step1< Tuple >
>;
template<class Tuple, class T>
using step3 = fmap_tuple_t<
    get_k_t,
    step2<Tuple, T>
>;
template<class Tuple, class...Targets>
using solution_base = std::tuple<
    fmap_tuple_t<
        std::add_lvalue_reference_t,
        step3<Tuple, Targets>
    >...
>;

struct A1{};
struct A2{};
struct A3{};

template<class Tuple>
using solution = solution_base<Tuple, A1, A2, A3>;

struct T1
{
    using type = std::tuple<A1, A2, A3>;
};

struct T2
{
    using type = std::tuple<A1, A2>;
};

struct T3
{
    using type = std::tuple<A1>;
};

using input = std::tuple<T1, T2, T3>;

using answer = std::tuple<std::tuple<T1&, T2&, T3&>, std::tuple<T1&, T2&>, std::tuple<T1&>>;
static_assert( std::is_same<answer, solution<input> >::value, "works" );