How/What to return in this case?
CODE:
vector<DWORD> get_running_proc_list()
{
DWORD proc_list[1024], size;
if(!EnumProcesses(proc_list, sizeof(proc_list), &size))
{
return 0; // PROBLEM HERE!!
}
vector<DWORD> _procs(proc_list, pro开发者_JS百科c_list + size/sizeof(DWORD));
return _procs;
}
ERROR:
cannot convert from 'int' to 'const std::vector<_Ty>'
What is the best possible way to fix this error?
Is there a better way than just returning an empty vector?Well, your function returns vector
, not DWORD
. Can't you return just an empty vector:
return std::vector< DWORD >();
or
return std::vector< DWORD >( 1, 0 );
If you really need the 0
?
EDIT:
There's another option, if empty vector is not a solution (in case, that it's some kind of valid value and you need to know) - use exception. You can make your own class for exception or use some standard one. So, you can do it like this:
if(!EnumProcesses(proc_list, sizeof(proc_list), &size))
{
throw MyException( "some message, if you want" );
}
I'd advice, if you choose this option, to inherit std::exception
.
Or, you can return pointer to std::vector
and return NULL
in this case. But I would not recommend this. But it's just my opinion.
Throw an exception. That's what they're for. After all, there definitely should be a list of processes that are running.
And definitely do not fail to return by value or something. In this case, the RVO/NRVO is trivially applied. I mean, at worst, you could swaptimize.
Edit: (after reading edited version of question)
Alternatives:
- You can make your function to return
void
and pass to it a vector by reference (or by pointer) then fill the vector in function body. - You can make your function to return
boost::shared_ptr<vector<DWORD> >
(or some other smart pointer), construct and fill the vector in function body (of course in dynamic memory), then return it's address or NULL. - Throw an exception if above solutions are not suitable.
if(!EnumProcesses(proc_list, sizeof(proc_list), &size))
{
vector<DWORD> empty;
return empty; <--- 0 sized vector
}
You can return an empty vector<>
.
As a side note, I would not recommend to return vector
by value. Instead pass the vector<>
as parameter to be assured that unnecessary copies will not happen.
void get_running_proc_list(vector<DWORD> &_procs) pass by reference and populate
{
...
}
Replace
return 0; // PROBLEM HERE!!
with
return vector<DWORD>(); // NO PROBLEM!!
How about a boost::optional
? It adds pointer semantics to normal objects and allows them to be either set or not, without dynamic allocation.
#include <boost/optional.hpp>
typedef boost::optional<std::vector<DWORD>> vec_opt;
vec_opt get_running_proc_list()
{
DWORD proc_list[1024], size;
if(!EnumProcesses(proc_list, sizeof(proc_list), &size))
{
return 0;
}
vector<DWORD> _procs(proc_list, proc_list + size/sizeof(DWORD));
return _procs;
}
And that's all you need to do, just change the return type. On the calling site:
vec_opt v = get_running_proc_list();
if(v){
// successful and you can now go through the vector, accessing it with *v
vector<DWORD>& the_v = *v;
// use the_v ...
}
You are trying to return two logically distinct bits of information: First, "What are the list of processes?" and second, "Can I compute the list of processes?". I suggest you return those in two distinct variables:
// UNTESTED
bool get_running_proc_list(vector<DWORD>& result)
{
DWORD proc_list[1024], size;
if(!EnumProcesses(proc_list, sizeof(proc_list), &size))
{
return false;
}
result = vector<DWORD>(proc_list, proc_list + size/sizeof(DWORD));
return true;
}
But, I might try to save a couple memcpy
's:
// UNTESTED
bool get_running_proc_list(vector<DWORD>& result)
{
result.clear();
result.resize(1024);
DWORD size;
if(!EnumProcesses(&result[0], result.size()*sizeof(DWORD), &size))
{
result.clear();
return false;
}
result.resize(size/sizeof(DWORD));
return true;
}
精彩评论