Hãy tưởng tượng tôi đã có struct này:Type-chỉ mẫu tranh luận để lambda
struct Foo {
operator int() {
return 11;
}
operator unsigned int() {
return 22;
}
} foo;
Khi struct này được đúc để một int, nó sẽ trả 11, nhưng khi đúc đến một int unsigned, nó sẽ trả 22.
sử dụng chức năng bình thường, tôi có thể sử dụng các mẫu và một hàm getter để lựa chọn:
template<typename T>
T get() {
return (T)foo;
}
Bây giờ, khi gọi hàm này như get<int>()
nó sẽ quay trở lại 11
, nhưng khi gọi nó là get<unsigned int>()
nó sẽ trả về 22
.
Tất cả mọi thứ của ổn cho đến bây giờ, khi tôi cố gắng sử dụng lambdas thay vì:
auto lambda=[](auto type) {
return (decltype(type))foo;
};
Bây giờ khi gọi lambda như lambda(0)
nó trả 11
, và gọi đó là như lambda(0U)
lợi nhuận 22
.
Điều này hoạt động chính xác, mặc dù khá 'hacky', nhưng một thể loại của loại cần phải được sử dụng, sẽ không lý tưởng với các loại lớn hơn. Vì vậy, một cách khác sanh ra, thậm chí 'hackier', để đạt được điều này:
auto lambda=[](auto* typePointer) {
return (decltype(*typePointer))foo;
};
Bây giờ gọi nó như lambda((int*)NULL)
lợi nhuận 11
nhưng gọi nó như lambda((unsigned int*)NULL)
lợi nhuận 22
. Như bạn có thể đã nhận thấy điều này là khá dài dòng và 'hacky', vì vậy tôi đã thử một phương pháp đơn giản hơn và truyền thống:
auto lambda=[]<typename T>() {
return (T)foo;
};
Lúc đầu, tôi nghĩ rằng nó sẽ không biên dịch, vì tôi chưa thấy cú pháp này bất cứ đâu, nhưng nó biên dịch (ít nhất là với GCC). Tuy nhiên, khi cố gắng gọi nó, lỗi xuất hiện:
lambda();
testlambda.cpp: In function ‘int main()’:
testlambda.cpp:25:9: error: no match for call to ‘(main()::<lambda()>)()’
lambda();
^
testlambda.cpp:22:29: note: candidate: template<class T> main()::<lambda()>
auto lambda=[]<typename T>() {
^
testlambda.cpp:22:29: note: template argument deduction/substitution failed:
testlambda.cpp:25:9: note: couldn't deduce template parameter ‘T’
lambda();
^
Như bạn có thể thấy, một ứng cử viên là template<class T> main()::<lambda()>
, nhưng điều này không biên dịch hoặc là:
lambda<int>()
->error: expected primary-expression before ‘int’
Vì vậy, câu hỏi của tôi là: Cách chính thức, tuân thủ tiêu chuẩn để thực hiện việc này, nếu có? Tôi thực sự hy vọng con trỏ hack không phải là cách duy nhất. Nó có vẻ thực sự vụng về để sử dụng trong mã thực.
Tôi đang sử dụng G ++ (GCC 5.4.0) làm trình biên dịch của mình. Tôi cũng đang sử dụng tiêu chuẩn C++ 14 như -std=c++14
.
Thường thì nó được thực hiện dưới dạng 'mẫu struct được nhập {typedef T type; }; '. Vượt qua nó và sử dụng 'typename decltype (param) :: type'. –