Ошибка шаблона: нет подходящего конструктора по умолчанию - PullRequest
2 голосов
/ 07 марта 2011

Дело в том, что я не (зная, пытаясь использовать любой конструктор по умолчанию beatle::beatle, ошибка:

1>  ecosystem.cpp
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\map(172): error C2512: 'beatle::beatle' : no appropriate default constructor available
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\map(165) : while compiling class template member function 'beatle &std::map<_Kty,_Ty>::operator [](int &&)'
1>          with
1>          [
1>              _Kty=tokenID,
1>              _Ty=beatle
1>          ]
1>          c:\users\zak\documents\visual studio 2010\projects\ascii_sivvure\ascii_sivvure\ecosystem.h(22) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled
1>          with
1>          [
1>              _Kty=tokenID,
1>              _Ty=beatle
1>          ]

Код с несущественными вещами убран:

заголовок:

typedef std::map<tokenID,beatle>    Beatles;

class ecosystem
{
private:
line 22:    Beatles m_Beatles;
};

source:

ecosystem::ecosystem(): m_output( output() )
{
    Beatles m_Beatles;
}

void ecosystem::populate()
{
    if (m_isMatingSeason && ( random(0,1000) < rateMATING ) )
    {
        beatle babyBeatle = breed();
        m_Beatles[babyBeatle.getTokenID()] = babyBeatle;
        m_field.occupy(babyBeatle.getTokenID(), babyBeatle.getLocation() );
    }
}

Я часами пытался использовать разные комбинации, пытаясь правильно определить / объявить maps. В какой-то момент intellisense начал говорить, что ему нужны указателивозразить здесь:

m_Beatles[babyBeatle.getTokenID()] = babyBeatle;

и это привело меня к печальному пути.

Все это происходит после моего первого (и, надеюсь, последнего) разгула рефакторинга, с тех пор как я провел более неделиЯ смог скомпилировать ... У меня, вероятно, есть 40 часов, чтобы снова попытаться заставить его работать.

Ответы [ 3 ]

2 голосов
/ 07 марта 2011

С исправлением, вызванным комментарием Адама Розенфилда ...

std::map<>::operator[] требует, чтобы тип значения имел общедоступный конструктор по умолчанию: вы просто должны иметь его в class beatle, если выхочу использовать эту функцию из std::map<>.Стандарт говорит, что можно создавать контейнеры из объектов, не конструируемых по умолчанию, до тех пор, пока вы не вызовете функции-члены с сигнатурами, указывающими заданные по умолчанию аргументы (см. Ниже), но на самом деле это не устраняет проблему std::map<>::operator[], котораяиспользует T (), несмотря на то, что не упоминает его в подписи.

20.1.4 - Конструкция по умолчанию [lib.default.con.req]

-1- Конструктор по умолчанию нетребуется.Некоторые сигнатуры функций-членов класса контейнера указывают конструктор по умолчанию в качестве аргумента по умолчанию.T () должно быть четко определенным выражением (dcl.init), если одна из этих сигнатур вызывается с использованием аргумента по умолчанию (dcl.fct.default).

Вы спрашиваете, означает ли это, что вы можете оставить переменные-члены неинициализированными в конструкторе по умолчанию.Да, если они не являются указателями, которые могут быть удалены с помощью operator= или деструктором - вам необходимо явно установить для них значение 0 / NULL.Если некоторые переменные-члены являются объектами со своими собственными конструкторами по умолчанию, их можно запускать независимо от того, нужны они вам или нет (т. Е. Даже если они просто устанавливают целочисленные значения, удваивают и т. Д.), Если оптимизация во время компиляции не сможет обнаружить это.они излишни.

2 голосов
/ 07 марта 2011

std::map<>::operator[] требуется конструктор по умолчанию.Это потому, что он сначала создает запись на карте, а затем operator=, который вы вызываете.

Если вы абсолютно хотите использовать std::map, но не хотите предоставлять конструктор по умолчанию (возможнонелогично для вашего случая?) вы можете использовать:

std::map<>::insert()

Чтобы явно вставить объект в код.Это немного усложняет задачу, потому что при поиске нужно также использовать find.

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

2 голосов
/ 07 марта 2011

Есть ли у класса beatle конструктор по умолчанию?Использование operator[] на std::map может создать запись на карте, если она не найдена с указанным вами ключом, и поэтому она должна иметь возможность создавать значения карты (здесь beatle).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...