Как использовать аргумент типа шаблона в лямбда?

Можно ли использовать аргумент типа шаблона из окружающей функции шаблона внутри локальной анонимной функции? Я почти уверен, что не могу объявить шаблонную лямбду...

Например, как мне сделать что-то вроде этого:

template <typename T>
void TrimString(std::basic_string<T>& str, const std::locale& loc = std::locale())
{
    // std::isspace as lambda unary predicate?
    auto fn = [&loc](T c){ return std::use_facet<std::ctype<T>>(loc).is(std::ctype_base::space, c); };
    // trim right
    str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(fn)).base(), str.end());
    // trim left
    str.erase(str.begin(), std::find_if(str.begin(), str.end(), std::not1(fn)));
}

В настоящее время это генерирует следующую ошибку:

error C2039: 'argument_type' : is not a member of '`anonymous-namespace'::<lambda0>'

Что имеет смысл, поскольку лямбда понятия не имеет об аргументе Tиз окружающей шаблонной функции.

Я использую VS2010 и gcc 4.7, но не хочу использовать boost.

Есть идеи?

Редактировать: Похоже, я ошибся в своем предположении, что проблема заключалась в самом аргументе шаблона. Скорее это использование std::not1, компилируемого с лямбда-функцией. Вот более подробный вывод об ошибке:

error C2039: 'argument_type' : is not a member of '`anonymous-namespace'::<lambda0>'
 : see declaration of '`anonymous-namespace'::<lambda0>'
 : see reference to class template instantiation 'std::unary_negate<_Fn1>' being compiled
          with
          [
              _Fn1=`anonymous-namespace'::<lambda0>
          ]
 : see reference to function template instantiation 'void TrimString<char>(std::basic_string<_Elem,_Traits,_Ax> &,const std::locale &)' being compiled
          with
          [
              _Elem=char,
              _Traits=std::char_traits<char>,
              _Ax=std::allocator<char>
          ]

Нужно ли явно объявлять тип аргумента, если это тип функции? Я все еще не уверен, что я делаю неправильно ...

Ответы:

Вариант 1: Если я не использую std::not1и вместо этого инвертирую возвращаемое значение в lambda я получаю такое же поведение без проблем.

auto fn = [&loc](T c){ return !std::use_facet<std::ctype<T>>(loc).is(std::ctype_base::space, c); };

Вариант 2: Поскольку лямбда больше не эквивалентна тому, как std::isspaceбудет вести себя как унарный предикат, приведение конструктора функционального объекта также помогает.

str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(std::function<bool(T)>(fn))).base(), str.end());
6
задан AJG85 21 June 2012 в 18:39
поделиться