As @user17732522 pointed out that the deleter of std::unique_ptr
is supposed to be callable with exactly one pointer as argument.
How can I retrieve the return value of pclose
when the unique_ptr is destroyed?
This code snippet does not compile,
#include<memory>
#include<iostream>
#include<string>
#include<cstdio>
int ExecCmd(const std::string& cmd, std::string& output)
{
int ret = 0;
{
std::unique_ptr<FILE, void(*)(FILE*, int*)> pipe(popen(cmd.c_str(), "r"), [](FILE* file, int* ret_ptr){
if(NULL==file)
{
*ret_ptr = -1;
}
else
{
*ret_ptr = pclose(file);
}
});
}
return ret;
}
int main()
{
}
Whereas this code snippet below compiles.
#include<memory>
#include<iostream>
#include<string>
#include<cstdio>
int ExecCmd(const std::string& cmd, std::string& output)
{
int ret = 0;
{
std::unique_ptr<FILE, void(*)(FILE*)> pipe(popen(cmd.c_str(), "r"), [](FILE* file){
if(NULL==file)
{
}
else
{
pclose(file);
}
});
}
return ret;
}
int main()
{
}
Here is what the compiler complains about the former code snippet:
In file included from /opt/compiler-explorer/gcc-11.3.0/include/c++/11.3.0/memory:76,
from <source>:1:
/opt/compiler-explorer/gcc-11.3.0/include/c++/11.3.0/bits/unique_ptr.h: In instantiation of 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = _IO_FILE; _Dp = void (*)(_IO_FILE*, int*)]':
<source>:20:27: required from here
/opt/compiler-explorer/gcc-11.3.0/include/c++/11.3.0/bits/unique_ptr.h:357:63: error: static assertion failed: unique_ptr's deleter must be invocable with a pointer
357 | static_assert(__is_invocable<deleter_type&, pointer>::value,
| ^~~~~
/opt/compiler-explorer/gcc-11.3.0/include/c++/11.3.0/bits/unique_ptr.h:357:63: note: 'std::integral_constant<bool, false>::value' evaluates to false
/opt/compiler-explorer/gcc-11.3.0/include/c++/11.3.0/bits/unique_ptr.h:361:24: error: too few arguments to function
361 | get_deleter()(std::move(__ptr));
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
I tried this code snippet to acquire the return value, but it does not compile:
#include<memory>
#include<iostream>
#include<string>
#include<cstdio>
int ExecCmd(const std::string& cmd, std::string& output)
{
int ret = 0;
{
std::unique_ptr<FILE, void(*)(FILE*)> pipe(popen(cmd.c_str(), "r"), [&ret](FILE* file){
if(NULL==file)
{
ret = -1;
}
else
{
ret = pclose(file);
}
});
}
return ret;
}
int main()
{
}
Could anybody shed some light on this matter?