I want to create a temporary copy of a const object and use it in a non-const way:
struct S {
S& f() { return *this; }
};
int main() {
const S a{};
S{a}.f(); // Error on this line
return 0;
}
Using msvc (Visual Studio 2017, C++14), I get this error:
Error C2662 'S &S::f(void)': cannot convert 'this' pointer from 'const S' to 'S &'
If I change the brace initialization to classic initialization, it works:
S{a}.f(); // Does not work
S(a).f(); // Works
Both variants compile fine in gcc. Am I missing something or is this a compiler bug?
It looks like a compiler bug, or the result of a weird optimization, because this variation of original code that only make ctors and dtor with side effects compiles fine using MSVC:
#include <iostream>
struct S {
S(const S& other) {
std::cout << "Copy ctor " << &other << " -> " << this << std::endl;
}
S() {
std::cout << "Default ctor " << this << std::endl;
}
~S() {
std::cout << "Dtor " << this << std::endl;
}
S& f() { return *this; }
};
int main() {
const S a{};
std::cout << &a << std::endl;
S{a}.f();
return 0;
}
Compilation is successful and output is:
Default ctor 0306FF07
Copy ctor 0306FF07 -> 0306FF06
Dtor 0306FF06
Dtor 0306FF07