对成员函数的模糊调用以在 lambda 中捕获 this

Posted

技术标签:

【中文标题】对成员函数的模糊调用以在 lambda 中捕获 this【英文标题】:Ambiguous call to member function for captured this in a lambda 【发布时间】:2017-08-24 13:21:51 【问题描述】:

我在尝试为捕获的this 调用 lambda 内的成员函数时遇到问题。该函数有 const 和非 const 版本,并且是在类型上模板化的。

以下代码演示了错误:

struct TEST

  template <typename T>
  void test() 

  template <typename T>
  void test() const 

  TEST()
  
    [this]()
    
      test<void>();
    ();
  
;

消息: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

我不确定这种行为是否正确,是否只是 Microsoft 编译器的问题,所以我在编译器资源管理器中使用 gcc 和 clang 测试了代码,它们都编译了代码而没有出现错误。

哪个编译器在此处显示正确的行为?

【问题讨论】:

Here's a repro with MSVC 【参考方案1】:

这是 MSVC 的问题。隐式 this 参数具有 cv 限定。这就是为什么在 cv 限定符上重载成员函数是可能的。在 c'tor 的主体中,this 指向一个非常量对象(初始化意味着我们必须修改该对象)。

这足以确定要调用的重载。

无论出于何种原因,MSVC 都感到困惑。但是,如果您通过显式访问this 指针来调用成员函数,那么混乱就消失了:

void bar()

  [this]()
  
    this->test<void>();
  ();
 

Live MSVC Example

【讨论】:

以上是关于对成员函数的模糊调用以在 lambda 中捕获 this的主要内容,如果未能解决你的问题,请参考以下文章

如何在 lambda 表达式中捕获单个类数据成员?

如何使用lambda表达式捕获局部变量?

访问 C++14 lambda 捕获,如结构成员

从通用 lambda 调用 `this` 成员函数 - clang vs gcc

如何使用 C++ lambda 将成员函数指针转换为普通函数指针以用作回调

如何从 $.getJSON 调用以 print_r() 方式打印关联数组?