【问题标题】:Weird "reference to non-static member function must be called" error奇怪的“必须调用对非静态成员函数的引用”错误
【发布时间】:2020-04-13 10:44:07
【问题描述】:

为什么我得到错误“必须调用非静态成员函数的引用”:

<source>:35:19: error: reference to non-static member function must be called

    list_.front().Set<Flags::First>(true);

    ~~~~~~~~~~~~~~^~~

<source>:40:10: note: in instantiation of member function 'List<int>::Set' requested here

    list.Set();

         ^

<source>:13:8: note: possible target for call

  void Set(bool value) {

       ^

1 error generated.

Compiler returned: 1

当我尝试用 clang 7.0.0 编译这段代码时?

#include <iostream>
#include <list>
using namespace std;

enum class Flags : uint8_t {
    First  = 1,
    Second = 2
};

class Header {
public:
  template <Flags flag>
  void Set(bool value) {
       flags_ = static_cast<Flags>(
           value
           ? (static_cast<uint8_t>(flags_) | static_cast<uint8_t>(flag))
           : (static_cast<uint8_t>(flags_) & (~static_cast<uint8_t>(flag))));
  }

private:
  Flags flags_{};
};

template <class T>
class List {
public:
    void Set();

private:
    std::list<Header> list_;
};

template <class T>
void List<T>::Set() {
    list_.front().Set<Flags::First>(true);
}

int main() {
    List<int> list;
    list.Set();
    return 0;
}

请看这里:https://godbolt.org/z/KXttBb

【问题讨论】:

标签: c++ clang


【解决方案1】:

我们可以分解如何诊断这个问题,以及修复的工作方式和原因。

<source>:35:19: error: reference to non-static member function must be called

好的,所以 clang 认为某些东西命名了一个非静态成员函数,并且您在其中使用它的表达式不是一个函数调用:

list_.front().Set<Flags::First>(true);

~~~~~~~~~~~~~~^~~

它非常明确地告诉我们,它将Set 识别为非静态成员函数,但是它认为Set&lt;Flags::First&gt;(true) 不是函数调用。

显然这正是调用函数模板的正确语法,所以问题在于 clang 没有将 Set 视为函数模板。


此时,一定要阅读上面cmets中链接的问题,以及accepted answer

...


对了,现在你已经读到了,很明显Set是一个依赖函数名,我们可以像这样添加template来解决这个问题:

list_.front().template Set<Flags::First>(true);

但这仍然留下了为什么这个名字是依赖的问题。我的意思是,阅读代码,我们知道list_.front() 必须有Header&amp; 类型,对吧?

所以让我们尝试明确地写出来:

Header &front = list_.front();
front.Set<Flags::First>(true);

我们看到(仍然使用 clang 8 或 9)现在 没有额外的 template 可以正常工作。如果你写auto &amp;front,问题又来了。

FWIW,这出现在 clang 8 和 9 中,但在 clang 10 中消失,并且似乎从未在 GCC 中发生。因此,它可能是一个错误,但至少您现在知道如何诊断它以及如何解决它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多