могут ли функторы, вызываемые из алгоритмов, действующих на карте, принимать пару <K, V> вместо value_type? - PullRequest
1 голос
/ 04 октября 2010

Я попытался написать короткую функцию для инвертирования std::map<K, V> (я знаю о boost.bimap, это для самообразования) и обнаружил, к моему удивлению, что код, который GCC 4.4 принимает с -pedantic - Настройки ANSI были отклонены как постоянные неверные SunCC (5.8, из 2005).

Поскольку value_type равно std::pair<const K, V>, SunCC настаивала на том, чтобы я постоянно уточнял мой тип K в аргументах функций, передаваемых transform() и for_each(), а также в типе возвращаемого значения быть переданным std::inserter, насколько я могу судить, это может быть правильно? Какой компилятор соответствовал стандартам?

#include <iostream>
#include <iterator>
#include <map>
#include <string>
#include <algorithm>
template<typename K, typename V>
std::pair<V, K> flip_pair(const std::pair<K, V>& p) // GCC/MSVC
//std::pair<const V, K> flip_pair(const std::pair<const K, V>& p) // SunCC
{
     return std::make_pair(p.second, p.first); // GCC/MSVC
//     return std::pair<const V, K>(p.second, p.first); // SunCC
}
template<typename K, typename V>
std::multimap<V, K> invert_map(const std::map<K, V>& in)
{
     std::multimap<V, K> out;
     transform(in.begin(), in.end(), std::inserter(out, out.begin()),
               flip_pair<K, V>);
     return out;
}
void print_pair(const std::pair<int, std::string>& p) // GCC/MSVC
//void print_pair(const std::pair<const int, std::string>& p) // SunCC
{
        std::cout << p.first << '\t' << p.second << '\n';
}
int main()
{
     std::map<std::string, int> map;
     map["foo"] = 1; map["bar"] = 2; map["baz"] = 3;
     std::multimap<int, std::string> revmap = invert_map(map);
     for_each(revmap.begin(), revmap.end(), print_pair);
}

1 Ответ

3 голосов
/ 04 октября 2010

Visual C ++ и g ++ верны;этот код (с flip_pair<K, V>() и const std::pair<K, V>&) в порядке.

Внутри transform, flip_pair<K, V> вызывается.Поскольку объект, передаваемый этой функции, является pair<const K, V>, создается временный объект типа pair<K, V> (pair имеет конструктор преобразования, который позволяет преобразовывать один тип пары в другой, если .first и .second типы являются конвертируемыми).

Этот временный объект передается в flip_pair<K, V>(), используя тот факт, что ссылка на const может быть связана с временным.

...