2015-08-04 2 views
0

У меня есть пользовательский метод, который выскакивает объект из очереди значения объектов как из параметра и возвращает код ошибки:C++ 11 Получить нестандартный построенный объект в качестве выходного параметра

class Element 
{ 
public: 
    Element() = delete; 

    Element(int32_t a, const std::string &s) 
    { 
     a_ = a; 
     s_ = s; 
    } 

private: 
    int32_t a_; 
    std::string s_; 
} 

enum class ErrorCode : uint32_t 
{ 
    OK = 0, 
    QueueEmpty, 
    QueueFull 
} 

class QueueWrapper 
{ 
public: 
    ErrorCode push(const Element &e) 
    { 
     // Implementation 
    } 

    ErrorCode pop(Element &outE) 
    { 
     // Simple example 

     if(queue_.empty()) 
     { 
      return ErrorCode::QueueEmpty; 
     } 

     outE = queue_.front(); 
     queue_.pop(); 

     return ErrorCode::OK; 
    } 

private 
    std::queue<Element> queue_; 
} 

void function() 
{ 
    QueueWrapper queueWrapper; 

    Element e1(1, "1"); 
    ErrorCode errorCode = queueWrapper.push(e1); 

    // What should I do here? 
    // Element e2; 
    // errorCode = queueWrapper.pop(e2); 
} 

Может Я получаю нестандартный объект в качестве выходного параметра, используя move семантика или другие механизмы?

+0

'Элемент pop (ErrorCode &);' Как в настоящее время реализовано, 'pop' требует' Element' для реализации оператора присваивания, но компилятор не может сгенерировать его из-за члена ссылочного типа. –

+0

Как выглядит конструктор с двумя параметрами 'Element'? Вы не можете привязать 's_' к' s', поэтому мне интересно, как 's_' инициализируется. Я предполагаю, что вы не хотите, чтобы 's_' был ссылкой. Объявите его как простой 'std :: string', тогда ваш' pop' должен работать как написанный. –

+0

'Элемент (int32_t a, константа std :: string &s);' должен быть 'Element (int32_t a, const std :: string &s);' –

ответ

1

Изменить подпись pop() вернуть элемент и не ErrorCode, то:

Element e(queueWrapper.pop()); 

Если Вы абсолютно должны иметь ERRORCODE, передать его в pop() по ссылке. НО коды ошибок действительно не являются современными C++. Ошибки следует в основном обращаться с исключениями, что приводит к чему-то больше, как это:

try { 
    ... 
    Element e(queueWrapper.pop()); 
    ... 
} 
catch (QueueWrapper::Exception & e) 
{ 
    // exception handling/reporting 
} 

Коды ошибок действительно должны использоваться только для пересечения границы модуля.

+0

Обратите внимание, что исключения в 'pop' обычно не являются безопасными для исключения, если они должны возвращать Кроме того, вы обычно используете отдельный 'top' и void-возвращающийся' pop' для этого – KABoissonneault

0

№ Если вы можете сформировать ссылку на Element, это значит, что она уже построена (или это будет сегмент памяти, а не Element).

Если вы хотите, чтобы функция каким-то образом получила назначенное пространство для создания объекта, дайте (N)RVO выполнить задание.