¿Es posible utilizar un argumento de tipo de plantilla desde una función de plantilla circundante dentro de una función anónima local? Estoy bastante seguro de que no se puede declarar una plantilla lambda ...¿Cómo usar el argumento de tipo de plantilla en lambda?
Por ejemplo ¿cómo voy a ir haciendo algo como esto:
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)));
}
Actualmente esto genera el siguiente error:
error C2039: 'argument_type' : is not a member of '`anonymous-namespace'::<lambda0>'
Lo cual tiene sentido ya que la lambda no tiene idea sobre el argumento T
de la función de plantilla circundante.
Uso VS2010 y gcc 4.7 pero no quiero utilizar boost.
¿Alguna idea?
Editar: Parece que estaba equivocado en mi suposición de que el problema era el argumento de la plantilla en sí. Más bien es el uso de std::not1
compilado con la función lambda. Aquí está la salida de error más detallado:
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>
]
¿Es necesario declarar explícitamente el tipo de argumento si se trata de un tipo de función? No estoy seguro de lo que estoy haciendo mal ... todavía
Respuestas:
Opción 1: Si yo no uso std::not1
y en lugar de negar el valor devuelto en la lambda consigo mismo comportamiento sin problema.
auto fn = [&loc](T c){ return !std::use_facet<std::ctype<T>>(loc).is(std::ctype_base::space, c); };
Opción 2: Desde el lambda no es ya equivalente a la forma std::isspace
se comportaría como un predicado unario un constructor fundido objeto función también hace el truco.
str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(std::function<bool(T)>(fn))).base(), str.end());
Por cierto, el mensaje de error parece indicar que el problema está en otra parte, específicamente con el lambda declarado en * namespace * scope. – Nawaz
Casting 'fn' como este' std :: not1 (std :: function (fn)) 'también funciona. –