Two int variables, one a reference, when captured by lambdas, differ in type in MSVC's c++20. Why?
Scott's technique to determine type at compile time produces expected results for c++14 and 17 but not for c++20. However, it seems this odd difference occurs in other compiles for earlier versions too.
Specifically, two ints, one a reference, when captured by either value or reference produce differing types. int and int &. Yet earlier versions produces expected types. When captured by value both were typed int. When captured by reference both were int &.
// Scott Meyer's compile time Type Deduction technique
template<typename T>
class TD;
int main()
{
int i{ 1 };
int& ri = i;
[i, ri]() mutable {
TD<decltype(i)> WhatAmI1; // c++14, c++17 TD<int>, c++20 TD<int>
TD<decltype(ri)> WhatAmI2; // c++14, c++17 TD<int>, c++20 TD<int &>
}();
[&i, &ri]() mutable {
TD<decltype(i)> WhatAmI3; // c++14, c++17 TD<int&>, c++20 TD<int>
TD<decltype(ri)> WhatAmI4; // c++14, c++17 TD<int&>, c++20 TD<int &>
}();
}
Exploring this further, the code produced is as expected and is the same for both captured values and captured references.
int main()
{
int i{ 1 };
int& ri = i;
[i, ri]() mutable {
i += 2;
ri += 3;
}();
[&i, &ri]() {
i += 2;
ri += 3;
}();
}
[i, ri]() mutable {
i += 2;
00007FF7F506187F 48 8B 85 E0 00 00 00 mov rax,qword ptr [this]
00007FF7F5061886 8B 00 mov eax,dword ptr [rax]
00007FF7F5061888 83 C0 02 add eax,2
00007FF7F506188B 48 8B 8D E0 00 00 00 mov rcx,qword ptr [this]
00007FF7F5061892 89 01 mov dword ptr [rcx],eax
ri += 3;
00007FF7F5061894 48 8B 85 E0 00 00 00 mov rax,qword ptr [this]
00007FF7F506189B 8B 40 04 mov eax,dword ptr [rax+4]
00007FF7F506189E 83 C0 03 add eax,3
00007FF7F50618A1 48 8B 8D E0 00 00 00 mov rcx,qword ptr [this]
00007FF7F50618A8 89 41 04 mov dword ptr [rcx+4],eax
[&i, &ri]() {
i += 2;
00007FF7F506190F 48 8B 85 E0 00 00 00 mov rax,qword ptr [this]
00007FF7F5061916 48 8B 00 mov rax,qword ptr [rax]
00007FF7F5061919 8B 00 mov eax,dword ptr [rax]
00007FF7F506191B 83 C0 02 add eax,2
00007FF7F506191E 48 8B 8D E0 00 00 00 mov rcx,qword ptr [this]
00007FF7F5061925 48 8B 09 mov rcx,qword ptr [rcx]
00007FF7F5061928 89 01 mov dword ptr [rcx],eax
ri += 3;
00007FF7F506192A 48 8B 85 E0 00 00 00 mov rax,qword ptr [this]
00007FF7F5061931 48 8B 40 08 mov rax,qword ptr [rax+8]
00007FF7F5061935 8B 00 mov eax,dword ptr [rax]
00007FF7F5061937 83 C0 03 add eax,3
00007FF7F506193A 48 8B 8D E0 00 00 00 mov rcx,qword ptr [this]
00007FF7F5061941 48 8B 49 08 mov rcx,qword ptr [rcx+8]
00007FF7F5061945 89 01 mov dword ptr [rcx],eax
}();
Link to compiler explorer https://godbolt.org/z/oe9KPcWWv