gpt4 book ai didi

c++ - 如何将 std::mutex 与其他一些类放在 std::tuple 中?

转载 作者:太空狗 更新时间:2023-10-29 22:59:36 26 4
gpt4 key购买 nike

我想要 std::shared_ptr<std::tuple<MyClass, std::mutex>> .

std::mutex既不可复制也不可移动。如何初始化?

最佳答案

两个参数的简单解决方案是 std::pairstd::piecewise_construct

std::tuple 缺少它。我认为这是一个缺陷。

如果我们想要 tuple(比如超过 2 个参数),我们可以使用一些可怕的代码来实现,因为“可以做到”的值有限。

template<class T>
struct placement_shared_helper {
std::aligned_storage_t<sizeof(T),alignof(T)> data;
T* get() { return reinterpret_cast<T*>(&data); }
template<class F>
void construct( F&& f ) {
std::forward<F>(f)((void*)&data);
}
// dangerous if construct throws:
~placement_shared_helper(){ get()->~T(); }
};

template<class T, class F>
std::shared_ptr<T> make_placement_shared( F&& f ) {
auto r1 = std::make_shared<placement_shared_helper<T>>();
r1->construct( std::forward<F>(f) );
return {r1->get(), r1}; // aliasing constructor
}

这需要您传入一个函数对象,当传递一个具有足够大小和对齐方式的 void* 时,它将在指向的存储中构造您的类型。

您可以提高 placement_shared_helper 的异常安全性,但这是工作而且我很懒。考虑从构造和 std::terminate 中捕获任何异常。

对于下一部分,我们作弊。这违反了标准,因为我们采用未初始化的内存并将其解释为元组以获取元组存储其对象的偏移量。糟糕的程序员。

template<class Dest, std::size_t...Is, class...Args>
void placement_construct( std::index_sequence<Is...>, Dest* here, std::tuple<Args...> args ) {
new((void*)here) Dest( std::get<Is>(args)... );
}
template<class Dest, class...Args>
void placement_construct( Dest* here, std::tuple<Args...> args ) {
return placement_construct( std::index_sequence_for<Args...>{}, here, std::move(args) );
}

template<class Dest, std::size_t...Is, class...Tuples>
void placement_construct_tuple( std::index_sequence<Is...>, void* here, Tuples... tuples ) {
using discard=int[];
(void)discard{0,(void(
placement_construct( &std::get<Is>(*(Dest*)here), std::move(tuples) )
),0)...};
}

template<class Dest, class...Tuples>
void placement_construct_tuple( void* here, Tuples... tuples ) {
placement_construct_tuple<Dest>( std::index_sequence_for<Tuples...>{}, here, std::move(tuples)... );
}

这假设一个元组只是在特定位置的一堆构造对象。我们获取我们的元组形内存块并依次构建它的每个元素。如果抛出异常,就会发生坏事;您可能想 try catch 终止。

make_placement_shared 采用一个函数,该函数采用 void* 并构造您的对象。

placement_construct_tuple 采用一组元组,并使用它们依次构造元组中的每个对象。

auto r = make_placement_shared<std::tuple<MyClass, std::mutex>>(
[&](void* here) {
placement_construct_tuple<std::tuple<MyClass, std::mutex>>(here,
std::forward_as_tuple( args_to_construct_MyClass_go_here ),
std::make_tuple() // no args for mutex
);
}
);

并排除拼写错误和未定义的行为,完成。

关于c++ - 如何将 std::mutex 与其他一些类放在 std::tuple 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36428450/

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