Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 341
Laccolith Avatar asked Aug 24 '17 13:08

Laccolith


1 Answers

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

like image 59
StoryTeller - Unslander Monica Avatar answered Nov 14 '22 21:11

StoryTeller - Unslander Monica