Вы можете создать файл .htaccess в корневой папке вашего проекта. Содержимое файла вроде этого;
RewriteEngine on
RewriteCond $1 !^(index\.php|assets)
RewriteRule ^(.*)$ /your-project/index.php/$1 [L]
template <typename K, typename V>
V get(std::map<K, V> const& map, K const& key)
{
std::map<K, V>::const_iterator iter(map.find(key));
return iter != map.end() ? iter->second : V();
}
Улучшенная реализация на основе комментариев:
template <typename T>
typename T::mapped_type get(T const& map, typename T::key_type const& key)
{
typename T::const_iterator iter(map.find(key));
return iter != map.end() ? iter->second : typename T::mapped_type();
}
Выбрасывание константы является неправильным, потому что оператор [] на map<> создаст запись, если она не будет присутствовать с созданной строкой значения по умолчанию. Если карта будет на самом деле в неизменном устройстве хранения данных затем, то это перестанет работать. Это должно быть так, потому что оператор [] возвращает ссылку неконстанты для разрешения присвоения. (например, m[1] = 2)
А быстрая бесплатная функция для реализации сравнения:
template<typename CONT>
bool check_equal(const CONT& m, const typename CONT::key_type& k,
const typename CONT::mapped_type& v)
{
CONT::const_iterator i(m.find(k));
if (i == m.end()) return false;
return i->second == v;
}
я буду думать о синтаксическом сахаре и обновлять, если я буду думать о чем-то.
...
непосредственный синтаксический сахар включил бесплатную функцию, которая делает map<>:: найдите (), и возвращает специальный класс, который переносит map<>:: const_iterator, и затем перегрузил оператор == () и оператор! = () для разрешения сравнения с отображенным типом. Таким образом, можно сделать что-то как:
if (nonmutating_get(m, "key") == "value") { ... }
я не убежден, что это намного лучше, чем:
if (check_equal(m, "key", "value")) { ... }
И это, конечно, намного более сложно и что продолжается, намного менее очевидно.
цель объекта, переносящего итератор, состоит в том, чтобы прекратить создавать значение по умолчанию объекты данных. Если Вы не заботитесь, то просто используют "получить" ответ.
В ответ на комментарий о получении быть предпочтенным по сравнению в надежде на нахождение некоторого будущего использования, у меня есть эти комментарии:
Говорят, что Вы имеете в виду: вызывание функции, вызванной "check_equal", проясняет, что Вы делаете сравнение равенства без создания объекта.
я рекомендую только реализовать функциональность, после того как у Вас есть потребность. Выполнение чего-то к тому времени является часто ошибкой.
В зависимости от ситуации, конструктор по умолчанию мог бы иметь побочные эффекты. Если Вы выдерживаете сравнение, почему делают что-либо дополнительное?
аргумент SQL: ПУСТОЙ УКАЗАТЕЛЬ не эквивалентен пустой строке. Является отсутствие ключа от Вашего контейнера действительно тем же, поскольку ключ, присутствующий в Вашем контейнере со значением по умолчанию, создал значение?
сказавший все это, значение по умолчанию созданный объект эквивалентен использованию map<>:: оператор [] на контейнере неконстанты. И возможно у Вас есть текущее требование для получить функции, которая возвращает значение по умолчанию созданный объект; я знаю, что у меня было то требование в прошлом.
find
идиоматическая форма. Выбрасывающий const
является почти всегда плохой идеей. Необходимо было бы гарантировать, что никакая операция записи не выполняется. В то время как это может обоснованно ожидаться доступа для чтения на карте, спецификация ничего не говорит об этом.
, Если Вы знаете , что значение существует, можно, конечно, предшествовать тесту с помощью count
(который довольно неэффективен, так или иначе, так как это означает пересекать карту дважды. Даже если Вы не знаете, существует ли элемент, я не использовал бы это. Используйте следующее вместо этого:
T const& item(map<TKey, T> const& m, TKey const& key, T const& def = T()) {
map<TKey, T>::const_iterator i = m.find(key);
return i == m.end() ? def : i->second;
}
РЕДАКТИРОВАНИЕ/: Как Chris правильно указал, конструкция по умолчанию объектов типа T
могла бы быть дорогой, тем более, что это сделано, даже если этот объект не на самом деле необходим (потому что запись существует). Если это верно, не используйте значение по умолчанию для def
аргумент в вышеупомянутом случае.
Действительно, оператор [] является неконстантой один на станд.:: карта, так как это автоматически вставляет пару "ключ-значение" в карту, если это не было там. (Побочные эффекты Oooh!)
правильный путь использует map::find
и, если возвращенный итератор допустим (!= map.end()
), возвращаясь эти second
, когда Вы показали.
map<int, int> m;
m[1]=5; m[2]=6; // fill in some couples
...
map<int,int>::const_iterator it = m.find( 3 );
if( it != m.end() ) {
int value = it->second;
// ... do stuff with value
}
Вы могли добавлять map::operator[]( const key_type& key ) const
в подклассе станд.:: карта Вы используете и утверждаете ключ, который будет найден, после которого Вы возвращаетесь it->second
.
Интересное в стороне, существует два пути, выполняют в шаблонном исследовании типа получить реализация, которая была принята (тот, который получает значение или возвращает значение по умолчанию созданный объект). Один, можно сделать то, что было принято, и имейте:
template <typename K, typename V>
V get1(const std::map<K, V>& theMap, const K const key)
{
std::map<K, V>::const_iterator iter(theMap.find(key));
return iter != theMap.end() ? iter->second : V();
}
или можно использовать тип карты и получить типы от этого:
template<typename T>
typename T::mapped_type
get2(const T& theMap, const typename T::key_type& key)
{
typename T::const_iterator itr = theMap.find(key);
return itr != theMap.end() ? itr->second : typename T::mapped_type();
}
преимущество этого состоит в том, что тип ключа, передаваемого в, не играет в исследовании типа, и это может быть что-то, что может быть неявно преобразовано в ключ. Например:
std::map<std::string, int> data;
get1(data, "hey"); // doesn't compile because the key type is ambiguous
get2(data, "hey"); // just fine, a const char* can be converted to a string
std::map<std::string, std::string>::const_iterator it( m.find("a") );
BOOST_CHECK_EQUAL(
( it == m.end() ? std::string("") : it->second ),
"b"
);
, Который не выглядит слишком плохо мне... Я, вероятно, не записал бы функцию для этого.
Продолжение идеи xtofl о специализации контейнера карты. Будет ли работать следующее хорошо?
template <typename K,typename V>
struct Dictionary:public std::map<K,V>
{
const V& operator[] (const K& key) const
{
std::map<K,V>::const_iterator iter(this->find(key));
BOOST_VERIFY(iter!=this->end());
return iter->second;
}
};