Có thể sử dụng đối số kiểu mẫu từ một hàm mẫu xung quanh trong một hàm ẩn danh cục bộ không? Tôi khá chắc chắn tôi không thể khai báo một mẫu lambda ...Làm thế nào để sử dụng đối số kiểu mẫu trong lambda?
Ví dụ làm thế nào tôi sẽ đi về làm một cái gì đó như thế này:
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)));
}
Hiện này tạo ra các lỗi sau:
error C2039: 'argument_type' : is not a member of '`anonymous-namespace'::<lambda0>'
Có ý nghĩa khi lambda không có đầu mối về đối số T
từ hàm mẫu lân cận.
Tôi sử dụng VS2010 và gcc 4.7 nhưng tôi không muốn sử dụng tăng.
Bất kỳ ý tưởng nào?
Chỉnh sửa: Dường như tôi đã sai khi giả định rằng vấn đề là chính đối số mẫu. Thay vào đó là việc sử dụng std::not1
được biên dịch với hàm lambda. Đây là kết quả lỗi chi tiết hơn:
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>
]
Bạn có cần tuyên bố rõ ràng loại đối số nếu đó là loại hàm không? Tôi không chắc chắn những gì tôi đang làm sai vẫn ...
Đáp:
Lựa chọn 1: Nếu tôi không sử dụng std::not1
và thay vào đó phủ nhận giá trị trả về trong lambda tôi nhận được cùng một hành vi không có vấn đề.
auto fn = [&loc](T c){ return !std::use_facet<std::ctype<T>>(loc).is(std::ctype_base::space, c); };
Lựa chọn 2: Kể từ khi lambda không dài tương đương với cách std::isspace
sẽ hành xử như một vị unary một đối tượng hàm constructor dàn diễn viên cũng thực hiện các trick.
str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(std::function<bool(T)>(fn))).base(), str.end());
BTW, thông báo lỗi dường như chỉ ra rằng sự cố nằm ở một nơi khác, cụ thể với lambda được khai báo ở phạm vi * không gian tên *. – Nawaz
Đúc 'fn' như thế này' std :: not1 (std :: function (fn)) 'cũng hoạt động. –