gpt4 book ai didi

c++ - 如何延迟初始化unique_ptrs的模板元组?

转载 作者:行者123 更新时间:2023-12-02 09:58:23 31 4
gpt4 key购买 nike

我需要编写一个基于异步回调创建数据快照的类。例如,如果我有一个整数流和一个双流,则必须将数据推送到队列中,并在它们两个都有值时对数据进行处理。我的课看起来像这样的atm:

template<typename... Types>
class Dataholder{
private:
std::deque<std::tuple<std::unique_ptr<Types>...>> data_frame_deque_;
public:
template <class T>
void push(T data); //find the next tuple that doesn't yet have value for type T and add it, or create new tuple
void run_if_frame_ready(std::function<void (std::tuple<std::unique_ptr<Types>...>)&> fun); //run function fun, that accepts a tuple as defined in data_frame_queue_;
}
用法示例应如下所示:
Dataholder<int, double> holder;
void myProcessingFunction(std::tuple<int,double>& data)
{
//do stuff
}
int main(void)
{
holder.push(42);
holder.push(3.14);
holder.run_if_frame_ready(myProcessingFunction);
}
Dataholder::push()函数检查队列中的每个元组,是否存在框架,如果存在,则是否初始化相应的值。如果不是,则对其进行初始化,如果是,则将其移至下一个数据帧/创建一个新的空帧并将数据放在此处。 Dataholder::run_if_frame_ready()函数检查队列中的第一帧是否已完全初始化。如果是,它将弹出并传递给给定的函数。
我的问题是,如何使用C++模板正确初始化所有成员?如何实现推送功能?我知道我可以使用 std::is_same之类的东西进行检查,但是我不太了解如何进行检查。目前,如果所有类型都只使用一次是可以的,但是是否可以用相同类型的多个条目来实现?例如。那么对于像 push(T data, int index)这样使用类的情况,则push函数可以是 Dataholder<int, int>

最佳答案

做这么简单的事情给我带来了巨大的困难,我感到非常惊讶。在这个实现中,您有一个双端队列(deque),最终效率与手工操作一样高效,即,您不会在队列中循环寻找空条目。

template<typename>
void get(); // for ADL

template<typename... Types>
class Dataholder{
using Deques = std::tuple<std::deque<std::unique_ptr<Types>>...>;

Deques deq;

template<typename F, size_t... Is>
void run(F&& f, std::index_sequence<Is...>)
{
std::forward<F>(f)(*(get<Is>(deq).front())...);
}

template<size_t... Is>
bool empty(std::index_sequence<Is...>) const
{
// mock fold expression
bool e = false;
char unused[] = {(e |= get<Is>(deq).empty())...};
(void)unused;
return e;
}

template<size_t... Is>
void pop(std::index_sequence<Is...>)
{
char unused[] = {(get<Is>(deq).pop_front(), 0)...};
(void)unused;
}

public:
// push by index
template<size_t I, typename T>
void push(T&& data)
{
using Tuple = std::tuple<Types...>;
using type = std::tuple_element_t<I, Tuple>;
get<I>(deq).emplace_back(new type(std::forward<T>(data)));
}

// push by type
template<typename T>
void push(T&& data)
{
using type = std::deque<std::unique_ptr<std::remove_reference_t<T>>>;
get<type>(deq).emplace_back(new auto(std::forward<T>(data)));
}

bool empty()
{
return empty(std::index_sequence_for<Types...>{});
}

void pop()
{
pop(std::index_sequence_for<Types...>{});
}

// you don't want std::function for this
template<typename F>
void run_if_frame_ready(F&& f)
{
if(empty())
return;
run(std::forward<F>(f), std::index_sequence_for<Types...>{});
}
};
并运行为
void f(int i, double d)
{
std::cout << i << ' ' << d;
}

int main()
{
Dataholder<int, double> holder;
holder.push(42);
holder.run_if_frame_ready(f); // does nothing
holder.push(3.14);
holder.run_if_frame_ready(f);
}

关于c++ - 如何延迟初始化unique_ptrs的模板元组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64046258/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com