我有以下无法编译的代码,今天是星期五,我有点疲惫。
#include <string>
#include <memory>
#include <utility>
#include <map>
template< typename T, typename ...Args >
std::unique_ptr< T > make_unique( Args && ...args )
{
return std::unique_ptr< T >( new T( std::forward< Args >( args )... ) );
}
struct A
{
};
std::map< std::string, std::unique_ptr< A > > _map = { { "A", make_unique< A >() } }; // <-- ERROR!!
下面编译没有问题
int main()
{
std::pair< std::string, std::unique_ptr< A > > p { "B", make_unique< A >() };
_map.insert( std::make_pair( "C", make_unique< A >() ) );
}
我得到的错误是(大致上,删除了 g++ 绒毛)
use of deleted function 'constexpr std::pair<...>( const st::pair<...> & )
'constexp std::pair<...>::pair( const std::pair<...> & ) is implicitly deleted because the default definition would be illegal.
啊!! 只需阅读 c++11 标准中的内容即可。
When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause
无赖!!!
有人知道初始化列表是否完全不可能吗?
最佳答案
对此您无能为力:复制初始化列表中的元素。这不会与仅移动的类相处。
有一种方法可以绕过这个“缺陷”,但它不太好读;你决定
using map_type = std::map< std::string, std::unique_ptr< A > >;
using pair_type = map_type::value_type;
pair_type elements[] = { { "A", std::make_unique< A >() }, { "B", std::make_unique< A >() } };
map_type myMap { std::make_move_iterator( begin(elements) ), std::make_move_iterator( end(elements) ) };
这将使 myMap
遍历范围并在其中移动元素,而不是复制。方法来自this其他问题。
关于C++ std::unique_ptr 存储在 std::map 中使用已删除的函数格式错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32268576/