Создание на глобальном уровне (C ++) - PullRequest
1 голос
/ 27 октября 2009

Я получаю следующую ошибку с кодом ниже.

expected constructor, destructor, or type conversion before '=' token

-

#include <string>
#include <map>

class Foo {

};

std::map<std::string, Foo> map;
map["bar"] = Foo();

int main()
{

    return 0;
}

Ответы [ 3 ]

13 голосов
/ 27 октября 2009
map["bar"] = Foo(); // This line is a statement not a declaration.
                    // You have to put it in main, or any execution context

Пока C ++ 0x не станет мейнстримом, я бы предложил использовать boost. Заполнение map становится куском пирога. Вот пример:

std::map<std::string, Foo> mymap;
...
int main()
{
  insert(mymap)
   ("First",  Foo(...))
   ("Second", Foo(...))
   ("Third",  Foo(...));
   ...
}
4 голосов
/ 27 октября 2009

Короткий ответ, как вы видели, таков: вы не можете этого сделать.

Я думаю, что вы действительно хотите это:

std::map<std::string, Foo> map;

int main()
{
    map["bar"] = Foo();

Если вам действительно нужна инициализация для выполнения до main(), вы часто будете видеть такие примеры:

namespace {
   struct StaticInitHelper {
       StaticInitHelper() { map["bar"] = Foo(); }
   } _helper_obj;
}

Однако теперь у вас возникла новая проблема, заключающаяся в том, что нет гарантии, что map будет создан до _helper_obj. Один из способов обойти это - объединить их:

namespace {
   struct StaticInitHelper : public std::map<std::string, Foo> {
       StaticInitHelper() { (*this)["bar"] = Foo(); }
   } map;
}

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

Еще одна альтернатива - определить класс с помощью std::map:

namespace {
   struct StaticInitHelper {
       StaticInitHelper() { map["bar"] = Foo(); }
       std::map<std::string, Foo> map;
   } map_holder;
}

map_holder.map.find(...

Но, конечно, это затрудняет любое использование карты.

Обновление:

Я забыл упомянуть другой вариант, используя boost::assign:

#include <boost/assign/list_of.hpp>

map<int,int> map = boost::assign::map_list_of(1,2)(2,3)(3,4)(4,5)(5,6);

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

1 голос
/ 27 октября 2009

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

...