2013-10-06 84 views
2

我使用的是SDL,遇到了一个我无法解决的问题。我想保持纹理(指向结构的指针)在std::map中,我使用std::string作为关键字,std::unique_ptr<texture, void(*)(texture*)>作为值。我必须使用std::unique_ptr中的删除器,因为纹理必须由某个函数释放。纹理也是由另一个函数创建的。我简化了代码,我下面有:为什么我不能用deleter创建这个unique_ptr?

#include <map> 
#include <memory> 

int* new_int(){ return new int; } 
void delete_int(int* p){ delete p; } 

typedef std::unique_ptr<int, void(*)(int*)> int_ptr; 

int main() 
{ 
    std::map<int, int_ptr> the_map; 
    the_map[1] = int_ptr(new_int(), delete_int); 
    return 0; 
} 

当我尝试编译在Visual Studio 2012这个代码中,我得到以下错误:

error C2338: unique_ptr constructed with null deleter pointer. 

,我觉得奇怪,因为我提供delete_int作为删除指针。 欢迎任何帮助,不同的方法也是如此。 在此先感谢!

+0

元素'[n]'的构造需要def ault-constructible类型,其中'unique_ptr'不是一个。考虑使用'.insert()'来代替'value_type'实例化。像'the_map.insert(std :: map :: value_type(1,int_ptr(new_int(),delete_int)));' – WhozCraig

+0

@WhozCraig'map :: emplace'是恕我直言的首选解决方案,请参阅我编辑的答案。 –

回答

4

这是因为使用map::operator[]要求值类型为缺省构造,在这种情况下一个unique_ptr不是。该存储指针的unique_ptr对象可能是空的,但删除器,如果它是一个指针,可能不为0,您可以用

the_map[1]; 

甚至只是

int_ptr p; 

检查这里面会给你完全相同的错误。

的解决方案是使用std::map::emplace

the_map.emplace(1, int_ptr(new_int(), delete_int)); 

如果因为它不是在你的环境中实施这是不可能的,你可以使用std::map::insert

the_map.insert(std::make_pair(1, int_ptr(new_int(), delete_int))); 

或更详细的,但稍微效率更高

the_map.insert(std::map<int, int_ptr>::value_type(1, int_ptr(new_int(), delete_int))); 
+1

或者'the_map.insert({1,int_ptr(new_int(),delete_int))})'(请注意{}) –

+0

@DaveS它可能比'emplace'效率低,但它实际上是'如果'emplace'不可用,插入''。尼斯。 –

+0

太棒了!非常感谢! – toteload

相关问题