2016-10-03 58 views
2

找不到什么在下面的代码的std ::的unique_ptr与拉姆达定制删除犯规编译

std::unique_ptr<CFStringRef, std::function<void(CFStringRef)>> 
cfstr(CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8), 
           [](CFStringRef obj){ 
            CFRelease(obj); 
           }); 

CFStringCreateWithCString问题应该返回正确的类型按CFStringCreateWithCString documentation

错误:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x c++ -arch x86_64 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=c++11 -stdlib=libc++ -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wno-unused-value -Wno-empty-body -Wno-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wno-constant-conversion -Wno-int-conversion -Wno-bool-conversion -Wno-enum-conversion -Wno-shorten-64-to-32 -Wno-newline-eof -Wno-c++11-extensions -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -fasm-blocks -fstrict-aliasing -Wdeprecated-declarations -Winvalid-offsetof -mmacosx-version-min=10.7 -g -fvisibility-inlines-hidden -Wno-sign-conversion -D_DEBUG -DDEBUG -MMD -MT dependencies -MF -c DynamicStore.cpp -o DynamicStore.o 

DynamicStore.cpp:29:5: error: no matching constructor for initialization of 'std::unique_ptr<CFStringRef, std::function<void (CFStringRef)> >' 
    cfstr((CFStringRef)CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8), 

main.cpp:73:14: note: in instantiation of function template specialization 'std::__1::for_each<std::__1::__wrap_iter<const std::__1::sub_match<const char *> *>, (lambda at main.cpp:73:45)>' requested here 
     std::for_each(cm.begin(), cm.end(), [](const std::cmatch &s){ 
      ^
main.cpp:73:45: note: candidate function not viable: no known conversion from 'const std::__1::sub_match<const char *>' to 'const std::cmatch' (aka 'const match_results<const char *>') for 1st argument 
     std::for_each(cm.begin(), cm.end(), [](const std::cmatch &s){ 
              ^
main.cpp:73:45: note: conversion candidate of type 'void (*)(const std::cmatch &)' 
+0

你能侧步这一问题,并为您提供类型的default_delete''专业化? –

+0

也似乎是,除非你的模板类型是一个指针,你需要定义一个包含'pointer' typedef的删除器,其中typedef是要传递给删除器的类型。否则它使用'T *'作为删除器的参数,在这种情况下这是错误的。这意味着在这种情况下lambda不适合定义删除器。 –

回答

3

构建上@NulledPointer报价:

struct CFStringRefDeleter { 
    using pointer = CFStringRef; 
    void operator()(CFStringRef ref) { 
     CFRelease(ref); 
    } 
}; 
using CFStr_t = std::unique_ptr<CFStringRef, CFStringRefDeleter>; 
CFStr_t cfstr(CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8)); 
CFStringRef obj = cfstr.get(); 
2

不确定这是否足够,但...如果我没有错,析构函数使用指向类型的指针,而不是类型的对象

我是说......你应该定义类型

std::unique_ptr<CFStringRef, std::function<void(CFStringRef *)>> 
                  ^ 
          note the pointer ---------------| 

和拉姆达应该接收(和使用)的指针

[](CFStringRef * pObj){ CFRelease(*pObj) /* ? */ }; 
+0

CFStringRef == CFString *。在std :: unique_ptr的情况下,Deleter调用'Deleter(T)',所以我不知道你是否正确 – PnotNP

+1

这是另一种方式。 unique_ptr的第一个模板参数应该是一个类型,而不是指向类型的指针。所以'std :: unique_ptr ' –

+0

@AndreyTurkin CFString是不透明的,所以不应该使用 – PnotNP

0

添加了“为什么”的一部分,以最大的回答是:

作为每unique_ptr DOC

-Deleter must be FunctionObject or lvalue reference to a FunctionObject or lvalue reference to function, callable with an argument of type unique_ptr<T, Deleter>::pointer

哪里unique_ptr<T, Deleter>::pointer是解释member types

unique_ptr<T, Deleter>::pointer = std::remove_reference<Deleter>::type::pointer if that type exists, otherwise T* . Must satisfy NullablePointer