是否可以在本地匿名函數中使用來自周圍模板函數的模板類型參數?我敢肯定,我不能申報模板拉姆達...如何在lambda中使用模板類型參數?
例如,我怎麼會去這樣做這樣的事情:
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,但我不想使用提升。
任何想法?
編輯:看來我錯了,我認爲問題是模板參數本身。相反,它是使用lambda函數編譯的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());
順便說一句,錯誤消息似乎表明問題在於其他地方,特別是在* namespace * scope聲明的lambda。 – Nawaz
像這樣'std :: not1(std :: function(fn))'鑄造'fn'也可以。 –