I have encountered an issue when trying to call a member function inside a lambda for a captured this
. There is a const and non-const version of the function and it is templated on a type.
The following code demonstrates the error:
struct TEST
{
template <typename T>
void test() {}
template <typename T>
void test() const {}
TEST()
{
[this]()
{
test<void>();
}();
}
};
Messages: http://rextester.com/MLU2098
source_file.cpp(13): error C2668: 'TEST::test': ambiguous call to overloaded function
source_file.cpp(7): note: could be 'void TEST::test<void>(void) const'
source_file.cpp(4): note: or 'void TEST::test<void>(void)'
source_file.cpp(13): note: while trying to match the argument list '()'
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64
I wasn't sure if this behaviour was correct and just an issue with the Microsoft compiler, so I tested the code with gcc and clang in the compiler explorer and they both compiled the code without an error.
Which compiler is displaying the correct behaviour here?
This is an issue with MSVC. The implicit this
parameter has a cv-qualification. That's why overloading a member function on a cv-qualifier is possible. In the body of the c'tor, this
points to a non-const object (initialization means we must modify the object after all).
This is enough to determine what overload to call.
For whatever reason, MSVC is confused. But if you call the member function by accessing the this
pointer explicitly, the confusion vanishes:
void bar()
{
[this]()
{
this->test<void>();
}();
}
Live MSVC Example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With