2013-10-09 3 views
3

Я разрабатываю Visual Studio 2010, а затем компилирую версию Linux 64 на другой машине. Для того, чтобы покрыть разницу между 2 разными компиляторами/средами, мы условно включают заявления:g ++ unordered_map не имеет функции at()?

#ifdef __linux__ 
#include <tr1/unordered_map> 
#endif 

#ifdef _WIN32 
#include <unordered_map> 
#endif 
using namespace std; // covers std::unordered_map 
using namespace std::tr1; // covers tr/unordered_map 

unordered_map<string,string> map; 

Для unordered_map, я использую эту документацию: cplusplus.com, который показывает в at() метод для поиска ключа в карта. (В отличие от оператора [], это не будет вставить ключ в карту, если не найден.)

Когда я попытался скомпилировать код на машине Linux, GCC выдает ошибку о том,

test_map.cpp:18: error: 'class std::tr1::unordered_map, std::allocator >, std::basic_string, std::allocator >, std::tr1::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator >, std::basic_string, std::allocator > > >, false>' has no member named 'at'

от версии НКУ на этой машине:

g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)

Я попытался компиляции на более новую установку Linux с версией:

gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)

и получил ту же ошибку.

Так мой вопрос имеет 2 части:

  • Есть работа вокруг, так что я по-прежнему можно использовать функцию unordered_map.at() ?

  • Где я могу найти документы API для Linux unordered_map так Я могу знать о любых других несоответствиях? (Я смотрел на GNU online docs, но я мог бы выяснить, где найти ссылку API, что показывает класс и функции.)

UPDATE

Я узнал многое из ответов, размещенных здесь, так что спасибо все. us2012's answer объяснил, как работать с проблемой компиляции, но в конце я переключился на использование boost::unordered_map, как было предложено John Dibling. (Я решил серьезно отнестись к предупреждениям об экспериментальных C++ 11, а также не желая непреднамеренно принудительно настроить параметры компилятора на клиентах, которые используют нашу библиотеку.) Это дало мне чистую компиляцию как в Windows, так и в Windows Linux, и не требовалось изменение кода (кроме удаления ссылки на std и tr1). Также я переключился на использование сайта http://cppreference.com, который уже выпрямил меня и с другими проблемами. (Удивительно, но этот сайт никогда не появлялся ни в одном из моих поисков Google для документов C++ API.)

Еще раз спасибо за подробные объяснения каждого.

+2

Не могу проверить это прямо сейчас, но я * думаю * в gcc 4.4.6 эти функции должны быть доступны через пространство имен 'std' вместо' tr1'. Попробуйте '#include ' и удалите 'using namespace std :: tr1' - и обязательно скомпилируйте с помощью' -std = C++ 0x'. Независимо от того, что вы используете, использование пространства имен с помощью 'std' и' std :: tr1', похоже, вызывает проблемы. – us2012

+5

Оба «tr1» и GCC 4.4 (не говоря уже о 4.1) сейчас являются доисторическими. Я понимаю, что у вас, вероятно, нет большого выбора, но вы должны иметь в виду, что документ применяется к стандарту C++ 11, не обязательно к 'tr1'. Для записи GCC 4.4 - с 2009 года ... – syam

+0

http://gcc.gnu.org/develop.html здесь. это действительно старый компилятор. –

ответ

4

GCC 4.4 уже поддерживает эти функции как часть -std=c++0x. Нет необходимости в пространстве имен tr1, а включение может быть только <unordered_map>.

В любом случае, не слишком либеральны с using namespace, особенно с пространствами имен, которые могут иметь значительное перекрытие, это становится большой проблемой. Дополнительные сведения об использовании пространств имен см. На странице GOTW.

+0

Что касается пространств имен, я согласен. Это то, что мы написали некоторое время назад (в то время как на самых ранних этапах обучения C++). В нашем более позднем коде мы стали намного более экономными с использованием «пространства имен». –

+0

Относительно использования 'std = C++ 0x' - я бы сильно отказался от использования этого для производственных работ. Он предшествует стандарту C++ 11, а сам gnu говорит, что поддержка C++ 0x * экспериментальная * в 4.4. –

1

Эквивалент должен быть:

mymap->find(key)->second 

find() дает итератор, поэтому вы должны проверить, что это не mymap.end().

4

Вы находитесь в довольно липкой точке.

GCC 4.4.6, который находится в дистрибутиве RHEL6, является pre-C++ 11. Библиотеки TR1 предшествуют C++ 11, и многие из компонентов, которые были введены в C++ 11, были значительно изменены с TR1 до того, как была завершена стандартизация.

unordered_map является одним из тех компонентов.

В дни TR1, unordered_map не было функции at(). Это присутствует в спецификации C++ 11.

Ваш компилятор VS2010 использует спецификацию C++ 11 (по крайней мере, для unordered_map, в некоторой степени), но GCC 4.4.6 не имеет понятия C++ 11. Вы компилируетесь на 2 разных языках.

Это все еще C++, по крайней мере на некотором уровне, поэтому должна быть возможность найти общий язык. Для чего это стоит, я не думаю, что лично использовал бы что-нибудь из TR1 для производства, но это я.

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

Суть для вас, я думаю, это. В GCC 4.4 поддержка C++ 0x (заметьте, что я не говорю C++ 11) является экспериментальной. Если бы это был я, я бы не использовал любую функциональность std=c++0x для производственных работ. Я бы также не использовал TR1 для производственных работ.

Это оставляет вам три варианта:

  1. Не используйте хэш-карту на всех
  2. Используйте хэш-карту от Boost, или другой авторитетной 3-й библиотеки партии
  3. Написать свой собственный хэш-карту.
+0

Я немного смущен вашим ответом - вы говорите, что не используете 'unordered_map' вообще в 4.4.6 или просто не используете метод' at() '? Кроме того, он скомпилировался с использованием флага '-std = C++ 0x'. Это также проблематично? –

+0

@SamGoldberg: Я попытался немного разъяснить. Я говорю, что не используйте любые функции C++ 0x из GCC 4.4 для производственных работ. Это только мое мнение. –

+0

@SamGoldberg: Кроме того, для быстрой онлайн-ссылки на язык C++ не используйте cplusplus.com. Он полон дезинформации. Вместо этого используйте cppreference.com, но, во что бы то ни стало, получите себе копию Стандарта. –

2

For unordered_map , I've been using this documentation: cplusplus.com, which shows an at() method to look up a key in the map.

Но вы не используете unordered_map, вы используете tr1::unordered_map. Это не одно и то же.

Документы, которые вы ищете, являются частью стандартной библиотеки C++ 11, которая была опубликована в 2011 году. Выпуск GCC, который вы используете, - с 2009 года. Неудивительно, что GCC 4.4 не поддерживает C++ 11 должным образом. TR1 не то же, что и C++ 11, контейнеры в TR1 являются ранними экспериментальными версиями и не включают в себя элемент at().

В любом случае, cplusplus.com мусор, ты лучше смотреть на http://cppreference.com

Is there a work around so I can still use the unordered_map.at() function?

std::tr1::unordered_map не имеет at() члена. Вы можете включить экспериментальную поддержку для C++ 0x («кодовое имя», используемое до завершения C++ 11) в GCC 4.4 с опцией -std=c++0x, что позволяет использовать версию GCC std::unordered_map, но требуя от клиентов сделать то же самое для использования ваш код - отличная идея.Придерживайтесь переносных функций, которые должным образом поддерживаются в вашей версии компилятора.

Where would I find the API docs for Linux unordered_map so I can be aware of any other discrepancies? (I looked at GNU online docs but I could figure out where to find the API reference that shows class and functions.)

Следуйте «стандартной библиотеки C++ Manual» ссылку, а затем «API и исходный документ» ссылка, то есть ссылка на ссылки API for the 4.4 release

Не забудьте проверить правильные документы, либо std::tr1::unordered_map, либо std::unordered_map, в зависимости от того, что вы пытаетесь использовать.

+0

Отменил мой ответ. –

+0

Ах спасибо, я уже его поддержал –

+0

Вопрос: клиенты, с которыми я проверил, также используют GCC 4.4. Мы поставляем им файл '.lib' и' .so' (они могут использовать то, что им нравится). 'Unordered_map' напрямую не подвергается им (хотя они могут получить к нему доступ, если они захотят), потому что он в основном предназначен для внутренней структуры данных в классе.Не могут ли они скомпилироваться без флага '-std = C++ 0x', если они либо: a) не получают прямого доступа к карте, либо b) получают доступ только к tr1 методам карты? –

 Смежные вопросы

  • Нет связанных вопросов^_^