I was writing some code dependent on type of variable and found out that referenced argument to function captured by value detected as reference type inside lambda body. I checked it with static_assert
for std::is_same_v
and decltype
.
Given code will be successfully compiled, but if I replace std::is_same_v<decltype(a),Loud&>
to std::is_same_v<decltype(a),Loud>
, the static_assert
will fail.
void foo(Loud& a) {
auto lamb = [a]() {
static_assert(std::is_same_v<decltype(a),Loud&>);
};
}
I expected that decltype(a)
is equal to Loud
, because it was copied.
Then I tried to check was it really copied with given code:
class Loud{
public:
Loud() {
cout << "ctor" << endl;
}
Loud(Loud& other) {
cout << "copy ctor" << endl;
}
};
void foo(Loud& a) {
auto lamb = [a]() {
static_assert(is_same_v<decltype(a),Loud&>);
};
}
int main()
{
Loud a;
foo(a);
return 0;
}
And I found that it was copied because I had copy ctor
line in my output.
After all of this I continued to experiment and was suprised that following code was successfully compiled
void foo(Loud& a) {
Loud b;
auto lamb = [a, b]() {
static_assert(is_same_v<decltype(a),Loud&>);
static_assert(is_same_v<decltype(b),Loud>);
};
}
Finally I am totally confused with this behavior. Can you please explain me what is going on here?