Списки инициализаторов C ++ - PullRequest
4 голосов
/ 18 августа 2011

Я должен заполнить std::vector элементами типа struct MHD_OptionItem. Эта структура имеет такую ​​реализацию:

struct MHD_OptionItem
{
    enum MHD_OPTION option;
    intptr_t value;
    void *ptr_value;
 };

Я пробовал так:

 vector<struct MHD_OptionItem> iov;
 if(...)
     iov.push_back({ MHD_OPTION_NOTIFY_COMPLETED, requestCompleted, NULL });
 if(...)
     iov.push_back({ MHD_OPTION_CONNECTION_TIMEOUT, connectionTimeout });
 [....]

но компилятор g ++, как и ожидалось, говорит мне:

warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x

Я знаю, что могу инициализировать временную структуру и затем передать ее в вектор, но этот метод мне кажется неэффективным и не таким элегантным.

Я не могу изменить структуру, вставляя конструктор, потому что это не мой код, а включенная библиотека.

Существует элегантный способ сделать это без использования синтаксиса c ++ 0x?

Ответы [ 4 ]

6 голосов
/ 18 августа 2011

Если вы не можете изменить struct или хотите оставить его в POD:

void f()
{
    struct {
        MHD_OptionItem operator ()(enum MHD_OPTION opt, intptr_t val, void *ptr = 0) {
            MHD_OptionItem x = {opt, val, ptr};
            return x;
        }
    } gen;

     vector<struct MHD_OptionItem> iov;
     if(...)
         iov.push_back(gen(MHD_OPTION_NOTIFY_COMPLETED, requestCompleted, NULL));
     if(...)
         iov.push_back(gen(MHD_OPTION_CONNECTION_TIMEOUT, connectionTimeout));
     [....]
}

Другое решение:

    struct Gen : MHD_OptionItem {
        Gen(enum MHD_OPTION opt, intptr_t val, void *ptr = 0) {
            option = opt;
            value = val;
            ptr_value ptr;
        }
    };

     vector<struct MHD_OptionItem> iov;
     if(...)
         iov.push_back(Gen(MHD_OPTION_NOTIFY_COMPLETED, requestCompleted, NULL));
     if(...)
         iov.push_back(Gen(MHD_OPTION_CONNECTION_TIMEOUT, connectionTimeout));
     [....]
0 голосов
/ 18 августа 2011

Как насчет введения конструктора и конструктора копирования,

struct MHD_OptionItem
{
  //...
  MHD_OptionItem(MHD_OPTION, intptr_t, void*);  // makes struct a non-POD
  MHD_OptionItem(const MHD_OptionItem&) // copy constructor
};

И используя его для инициализации,

iov.push_back(MHD_OptionItem(MHD_OPTION_NOTIFY_COMPLETED, requestCompleted, NULL));

Да, вы вводите временный. Но все же синтаксис остается элегантным

0 голосов
/ 18 августа 2011

Может быть, вы можете предоставить конструктор, принимающий все 3 параметра, а затем создать его следующим образом:

iov.push_back(MHD_OptionItem( MHD_OPTION_NOTIFY_COMPLETED, requestCompleted, NULL));
0 голосов
/ 18 августа 2011

Вы должны создать конструктор для своей структуры.

struct MHD_OptionItem
{
    MHD_OptionItem(enum MHD_OPTION _option, intptr_t _value, void *_ptr_value)
    : option(_option), value(_value), ptr_value(_ptr_value) {}
    enum MHD_OPTION option;
    intptr_t value;
    void *ptr_value;
};

Тогда вы можете инициализировать следующим образом:

ov.push_back(MHD_OptionItem(MHD_OPTION_NOTIFY_COMPLETED, requestCompleted, NULL));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...