Ale*_*eus 4 c++ constructor tuples copy move
我正在尝试创建一个对象,该对象存储从函数创建的对象元组,static但是当tuple创建时,对象被复制到tuple而不是直接放入其中,调用两次中每个对象的析构函数tuple,这是一种行为我想避免。有没有办法解决这个问题,而不必为每个插件类创建自定义移动/复制构造函数?
代码如下:
#include <tuple>
#include <iostream>
namespace details
{
template<typename PluginT, typename ContainerT, typename TupleT, size_t... Is>
static PluginT construct_plugin(ContainerT& container, TupleT&& tuple, std::index_sequence<Is...>)
{
return PluginT(container, std::get<Is>(std::forward<TupleT>(tuple))...);
}
template<typename PluginT, typename ContainerT, typename TupleT>
static PluginT construct_plugin(ContainerT& container, TupleT&& tuple)
{
return construct_plugin<PluginT>(container, std::forward<TupleT>(tuple), std::make_index_sequence<std::tuple_size<std::decay_t<TupleT>>::value>{});
}
}
struct simple_plugin
{
template<typename ContainerT>
simple_plugin(ContainerT& container) {}
~simple_plugin()
{
std::cout << "simple_plugin destructor" << std::endl;
}
};
struct plugin_with_params
{
template<typename ContainerT>
plugin_with_params(ContainerT& container, int argc, char* argv[]) {}
~plugin_with_params()
{
std::cout << "plugin_with_params destructor" << std::endl;
}
};
template<typename... PluginTs>
struct plugin_container
{
std::tuple<PluginTs...> plugins;
template<typename... TupleTs>
plugin_container(TupleTs&&... tuples) :
plugins(details::construct_plugin<PluginTs>(*this, std::forward<TupleTs>(tuples))...) {}
};
int main(int argc, char* argv[])
{
plugin_container<simple_plugin, plugin_with_params> container(std::make_tuple(), std::make_tuple(argc, argv));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是实际的行为: https://godbolt.org/z/bqjv5r88x
struct nocopy{
nocopy(){}
nocopy(nocopy const&)=delete;
nocopy(nocopy&&)=delete;
};
struct maker{
operator nocopy()const{return {};}
};
std::tuple<nocopy,nocopy> t( maker{}, maker{} );
Run Code Online (Sandbox Code Playgroud)
这会绕过c++17或更高版本中的复制构造函数。
类似的技术可用于获取返回对象的任意函数。
诀窍在于,没有接受该maker对象的构造函数,然后 C++ 会调用 的转换运算符maker,其返回值可以直接省略到对象中。
在 17 之前,这可能会在运行时绕过复制构造函数,但除非复制(或移动)存在(即使复制/移动构造函数有副作用),否则不会编译。这是因为 17 添加了保证省略;在此之前它是可选的。
| 归档时间: |
|
| 查看次数: |
313 次 |
| 最近记录: |