Laccolith
Laccolith

Reputation: 123

Ambiguous call to member function for captured this in a lambda

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?

Upvotes: 7

Views: 621

Answers (1)

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

Upvotes: 7

Related Questions