std::unique_ptr 使用 lambda 自定义删除器无法编译
std::unique_ptr with lambda custom deleter doesnt compile
在下面的代码中找不到问题所在
std::unique_ptr<CFStringRef, std::function<void(CFStringRef)>>
cfstr(CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8),
[](CFStringRef obj){
CFRelease(obj);
});
CFStringCreateWithCString 应该 return 根据 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 &)'
不确定这是否足够但是...如果我没记错的话,析构函数使用指向该类型的指针,而不是该类型的对象
我的意思是...您应该将类型定义为
std::unique_ptr<CFStringRef, std::function<void(CFStringRef * )>>
^
note the pointer ---------------|
并且 lambda 应该接收(并使用)一个指针
[](CFStringRef * pObj){ CFRelease(*pObj) /* ? */ };
将 "why" 部分添加到 max 的答案中:
根据 unique_ptr 文档
-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
基于@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();
在下面的代码中找不到问题所在
std::unique_ptr<CFStringRef, std::function<void(CFStringRef)>>
cfstr(CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8),
[](CFStringRef obj){
CFRelease(obj);
});
CFStringCreateWithCString 应该 return 根据 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 &)'
不确定这是否足够但是...如果我没记错的话,析构函数使用指向该类型的指针,而不是该类型的对象
我的意思是...您应该将类型定义为
std::unique_ptr<CFStringRef, std::function<void(CFStringRef * )>>
^
note the pointer ---------------|
并且 lambda 应该接收(并使用)一个指针
[](CFStringRef * pObj){ CFRelease(*pObj) /* ? */ };
将 "why" 部分添加到 max 的答案中:
根据 unique_ptr 文档
-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, otherwiseT*
. Must satisfy NullablePointer
基于@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();