【问题标题】:Meaning of class(*)() in gccgcc中class(*)()的含义
【发布时间】:2023-03-17 17:27:01
【问题描述】:

我无法理解这个编译器错误。我在帖子标题中写了 class(*)() 是因为我正在实例化的类被称为“不透明”,但该名称并不提供信息或相关。它是一个模板化的循环缓冲区和一些测试。我正在使用 opaque 类来测试具有完整类/结构类型的数据结构。我也在使用原语(目前是 int)进行测试,并且该测试函数不会给我这个编译器错误。还有比这更多的代码,但我提供了我认为相关的部分。 如果您有兴趣,完整代码是here。

gcc 错误:

tests.cpp: In function ‘bool opaque_fill_test(int)’:
tests.cpp:97:23: error: no matching function for call to ‘CircBuf<opaque>::remove(opaque (*)())’

tests.cpp:

struct opaque {
  int id;
  opaque(int n): id(n) {} 
  opaque operator=(const opaque &o) { this->id = o.id; }
};

opaque rcv();
CircBuf<opaque> c(size);
for (int i=0; i<size; i++) {
    if ( c.remove(&rcv)) {
        if (rcv.id != i ) {
            cout << "wrong value: " << rcv << " "
            << "should be: " << i << endl;
            return false;
        }
    } else {
        cout << "remove fail at i=" << rcv << endl;
        return false;
    }
}

CircBuf.h:

template<typename T> class CircBuf {
    ...
    template<typename T> bool CircBuf<T>::remove(T *t) {
       ...
       *t = data[front];
       ...

如果我声明一个 opaque* 并将其传递给删除:

opaque rcv();
opaque* p = &rcv;
for (int i=0; i<size; i++) {
  if ( c.remove(p)) {
    ...
    ...

我收到类似的错误:

tests.cpp: In function ‘bool opaque_fill_test(int)’:
tests.cpp:96:16: error: cannot convert ‘opaque (*)()’ to ‘opaque*’ in initialization

【问题讨论】:

    标签: c++ templates gcc most-vexing-parse


    【解决方案1】:

    如果您有声明foo x();,则表达式&amp;x 实际上是一个函数指针,可分配给foo *(y)() 之类的东西。您上一个示例中的 p 变量不是这样的函数指针,而只是指向 opaque 结构的指针。因此,您不能将函数指针分配给该变量。

    [编辑] 刚刚记住:也许您打算声明一个opaque 变量并使用默认构造函数对其进行初始化。然后省略括号。这是 C 中遗留下来的语法。如果您实际上将值放在中间以调用不同的构造函数,则只能在其中使用括号。

    【讨论】:

    • 我相信opaque rcv(); 在函数定义中,在这种情况下,它只是一个常规函数声明,而不是一个方法。否则错误消息不应显示opaque (*)(),而是类似opaque (class::*)()。
    • 已修复,谢谢。但关键是,他将指向数据的指针与指向可执行代码的指针混合在一起,编译器理所当然地抱怨。 ;) 我的猜测是他误将foo bar(); 语法用于使用默认构造函数进行初始化。
    • opaque 没有默认构造函数,所以 opaque rcv; 不应该编译。
    【解决方案2】:

    你在做什么:

    opaque rcv();
    

    是您正在“声明一个函数”,名称为rcv,返回类型为opaque,并且不带任何参数。 Check this link

    去掉括号:

    opaque rcv;
    

    【讨论】:

      【解决方案3】:

      你点击了most vexing parse。

      如果我声明一个 opaque* 并将其传递给删除:

      opaque rcv();
      

      这声明了一个返回 opaque 的函数,而不是默认初始化的 opaque。请改用opaque rcv; 或opaque rcv = {};。

      至于错误信息,opaque (*)() 是指向返回opaque 的函数的指针类型。 “函数”的名称在用于调用以外的其他内容时被隐式转换为指针。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-01
        • 1970-01-01
        • 2021-03-29
        • 1970-01-01
        • 2018-11-07
        • 1970-01-01
        • 2016-12-13
        相关资源
        最近更新 更多