Как я могу использовать decltype для доступа к зависимому типу? - PullRequest
4 голосов
/ 18 ноября 2011

Во-первых: мои извинения за неправильную номенклатуру!

По сути, у меня есть не слишком необычное желание объявить контейнер на основе стека, например:

std::map<CString, size_t> ecounts;

Затем я хочу перебрать содержимое ecounts немного дальше в теле функции, но я действительно не хочу ни набирать кучу вещей, ни перепечатывать вышеупомянутые типы, чтобы компилятор работать с тем, что у меня есть ...

std::foreach(ecounts.begin(), ecounts.end(), [&] (>>>here is the problem<<< e)
{
  ... whatever I want to do with e ...
}

Конечно, я могу использовать typedefs или мои знания об объявлении ecounts вручную:

std::foreach(ecounts.begin(), ecounts.end(), [&] (std::pair<CString,size_t> e)
...

Но, блин! Я бы предпочел иметь единственное объявление о том, что такое ecounts, и просто как-то использовать его value_type. Но это, похоже, не работает:

std::foreach(ecounts.begin(), ecounts.end(), [&] (decltype(ecounts)::value_type e)
...

Это просто ограничение моего компилятора (vs2010), или это ограничение C ++?

Как я мог бы создать своего рода одно правило определения для такого кода, предпочтительно без необходимости использовать typedefs для его достижения (т. Е. Я могу сделать следующее):

typedef std::map<CString, size_t> maptype;
typedef maptype::value_type valuetype;
maptype ecounts;
...
std::foreach(ecounts.begin(), ecounts.end(), [&] (valuetype e)
...

Это, конечно, не конец света, но если бы я мог использовать decltype, я был бы счастлив от полученного сокращения мышления и возврата к прежним результатам ...

Ответы [ 2 ]

8 голосов
/ 18 ноября 2011

Ограничение VS2010, так как желаемое дополнение вошло в стандарт слишком поздно для него.Он должен компилироваться с соответствующим компилятором.Для работы просто используйте decltype(*ecounts.begin()) e.Или шаблон личности:

template<class T>
struct identity{ typedef T type; };
// usage: identity<decltype(ecounts)>::type::value_type
2 голосов
/ 18 ноября 2011

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

for (auto e: ecounts)
{
   // whatever you want to do with e
}

Или, если вы хотите изменить элементы на карте:

for (auto& e: ecounts)
{
  // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...