ローカル無名関数内で周囲のテンプレート関数からテンプレート型引数を使用することは可能ですか? テンプレートラムダを宣言できないと確信しています...
たとえば、次のようなことを行うにはどうすればよいですか。
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
ラムダで返された値を使用せずに否定すると、問題なく同じ動作が得られます。
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());