c++ - type of reference-captured object inside lambda -


the following code works gcc

#include <map>  int main() {     std::map<int, double> dict;     const auto lambda = [&]()     {         decltype(dict)::value_type bar;     }; } 

but msvc have additionally use std::remove_reference

#include <map> #include <type_traits>  int main() {     std::map<int, double> dict;     const auto lambda = [&]()     {         std::remove_reference_t<decltype(dict)>::value_type bar;     }; } 

otherwise an error:

error c2651: 'std::map<int,double,std::less<_kty>,std::allocator<std::pair<const _kty,_ty>>> &': left of '::' must class, struct or union 

which compiler shows correct behaviour according standard?

update:

for msvc decltype(dict) reference, following code

#include <map>  int main() {     std::map<int, double> dict;     const auto lambda = [&]()     {         decltype(dict) foo;     }; } 

errors with

error c2530: 'foo': references must initialized 

if wrong behaviour, lead nasty bugs, dangling references when code compiled msvc.

#include <map>  std::map<int, double> return_a_map() {     std::map<int, double> result;     return result; }  int main() {     std::map<int, double> dict;     const auto lambda = [&]()     {         decltype(dict) foo = return_a_map();         // foo dangling reference in msvc     }; } 

there no special rule regarding non parenthesized applications of decltype (ie. [expr.prim.lambda]/20 not apply). fall usual definition of decltype, mandates if operand id-expression, yielded type declared type of entity, , that's not reference type. hence vc++ wrong.

nb: doesn't matter whether dict captured or not, because ¶17:

every id-expression within compound-statement of lambda-expression that odr-use (3.2) of entity captured copy transformed access corresponding unnamed data member of closure type. [ note: an id-expression not odr-use refers original entity, never member of closure type. furthermore, such id-expression not cause implicit capture of entity. — end note ]

decltype never odr-uses of operands or suboperands. rule gets pretty problematic @ times, e.g. shown in core issue 958:

int f (int&); void* f (const int&);  int main() {    int i;    [=] ()-> decltype(f(i)) { return f(i); }; } 

here, decltype(f(i)) uses non-const i enclosing scope. however, since lambda isn't mutable, i in body const, hence trailing-return-type incorrect. cwg concluded arises infrequently worth solving.


Comments

Popular posts from this blog

asynchronous - C# WinSCP .NET assembly: How to upload multiple files asynchronously -

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -