Как / Что вернуть в этом случае? - PullRequest
5 голосов
/ 23 июня 2011

КОД:

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, proc_list + size/sizeof(DWORD));
    return _procs;
}

ОШИБКА:

cannot convert from 'int' to 'const std::vector<_Ty>'

Какой самый лучший способ исправить эту ошибку?
Есть ли лучший способ, чем просто вернуть пустой вектор?

Ответы [ 7 ]

4 голосов
/ 23 июня 2011

Ну, ваша функция возвращает vector, а не DWORD.Разве вы не можете вернуть только пустой вектор:

return std::vector< DWORD >();

или

return std::vector< DWORD >( 1, 0 );

Если вам действительно нужен 0?


РЕДАКТИРОВАТЬ :

Есть еще один вариант, если пустой вектор не является решением (в случае, если это какое-то действительное значение, и вам нужно знать) - использовать исключение.Вы можете создать свой собственный класс для исключения или использовать какой-нибудь стандартный.Итак, вы можете сделать это так:

if(!EnumProcesses(proc_list, sizeof(proc_list), &size))
{
   throw MyException( "some message, if you want" );
}

Я бы посоветовал, если вы выберете эту опцию, наследовать std::exception.

Или вы можете вернуть указатель на std::vector и вернуть NULL в этом случае.Но я бы не рекомендовал бы это.Но это только мое мнение.

3 голосов
/ 24 июня 2011

Брось исключение. Вот для чего они. В конце концов, определенно должен быть список запущенных процессов.

И, конечно же, не обойтись без возврата по значению или чему-то еще. В этом случае RVO / NRVO применяется тривиально. Я имею в виду, в худшем случае, вы могли бы swaptimize.

2 голосов
/ 23 июня 2011

Редактировать: (после прочтения отредактированной версии вопроса)

Альтернативы:

  1. Вы можете заставить свою функцию возвращать void и передавать ей вектор по ссылке (или по указателю), а затем заполнить вектор в теле функции.
  2. Вы можете заставить свою функцию возвращать boost::shared_ptr<vector<DWORD> > (или некоторый другой умный указатель ), создавать и заполнять вектор в теле функции (конечно, в динамической памяти), а затем возвращать его адрес или NULL.
  3. Бросьте исключение, если вышеуказанные решения не подходят.
1 голос
/ 24 июня 2011

Как насчет boost::optional?Он добавляет семантику указателей к обычным объектам и позволяет их устанавливать или не устанавливать без динамического выделения.

#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;
}

И это все, что вам нужно сделать, просто изменить тип возвращаемого значения.На сайте звонка:

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 ...
}
1 голос
/ 23 июня 2011

Заменить

return 0; // PROBLEM HERE!!  

с

return vector<DWORD>(); // NO PROBLEM!!  
1 голос
/ 23 июня 2011
if(!EnumProcesses(proc_list, sizeof(proc_list), &size))
{
  vector<DWORD> empty;       
  return empty;  <--- 0 sized vector
}

Вы можете вернуть пустое vector<>.

В качестве примечания, я бы не рекомендовал возвращать vector по значению .Вместо этого передайте vector<> в качестве параметра, чтобы быть уверенным, что ненужных копий не произойдет.

void get_running_proc_list(vector<DWORD> &_procs) pass by reference and populate
{
...
}
0 голосов
/ 24 июня 2011

Вы пытаетесь вернуть два логически различных бита информации: во-первых, «Что такое список процессов?» и второе: «Могу ли я вычислить список процессов?». Я предлагаю вам вернуть их в двух разных переменных:

// 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;
}

Но я мог бы попытаться спасти пару memcpy:

// 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;
}
...