Ist es möglich, ein Template-Argument aus einer umgebenden Template-Funktion innerhalb einer lokalen anonymen Funktion zu verwenden? Ich bin mir ziemlich sicher, dass ich nicht eine Vorlage Lambda erklären kann ...Wie Template-Argument in Lambda verwenden?
Zum Beispiel, wie würde ich mich über so etwas wie dies zu tun:
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)));
}
Derzeit wird diese erzeugt die folgende Fehlermeldung:
error C2039: 'argument_type' : is not a member of '`anonymous-namespace'::<lambda0>'
Das ist sinnvoll, da das Lambda keine Ahnung über das Argument T
von der umgebenden Template-Funktion hat.
Ich benutze VS2010 und gcc 4.7, aber ich möchte nicht boost verwenden.
Irgendwelche Ideen?
Bearbeiten: Es scheint, ich lag falsch in meiner Annahme, dass das Problem das Template-Argument selbst war. Vielmehr wird die Verwendung von std::not1
mit der Lambda-Funktion kompiliert. Hier ist die ausführlichere Fehlerausgabe:
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>
]
Müssen Sie explizit den Typ für das Argument erklären, wenn es eine Funktion Typ ist? Ich bin mir nicht sicher, was ich falsch mache noch ...
Antworten:
Option 1: Wenn ich nicht std::not1
verwenden Sie stattdessen den zurückgegebenen Wert in der Lambda-negieren ich das gleiche bekommen Verhalten ohne Problem.
auto fn = [&loc](T c){ return !std::use_facet<std::ctype<T>>(loc).is(std::ctype_base::space, c); };
Option 2: Da das Lambda nicht mehr gleichwertig ist, wie std::isspace
als einstelliges Prädikat verhalten würde eine Funktion Objektkonstruktor Besetzung auch den Trick funktioniert.
str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(std::function<bool(T)>(fn))).base(), str.end());
BTW scheint die Fehlermeldung anzuzeigen, dass das Problem woanders liegt, speziell mit dem Lambda deklariert * Namespace * Bereich. – Nawaz
Casting 'fn' wie folgt' std :: not1 (std :: function (fn)) 'funktioniert auch. –