【问题标题】:error: request for member '..' in '..' , which is of non-class type [duplicate]错误:在“..”中请求成员“..”,这是非类类型[重复]
【发布时间】:2018-02-11 20:50:13
【问题描述】:

我使用 STL priority_queue 并提供一个自定义比较器类,其构造函数接收指向存储优先级的向量的指针,因此 -

#include <iostream>
#include <queue>          // std::priority_queue
#include <vector>         // std::vector

using namespace std;

class CompareReachDist
{
    const vector<float> *reach_dists;
public:
    CompareReachDist(const vector<float> *input)
    {
        reach_dists = input;
    }

    bool operator() (const size_t &l, const size_t &r) const
    {
        return (reach_dists->at(l) > reach_dists->at(r));
    }
};

typedef priority_queue<size_t, vector<size_t>, CompareReachDist> pq;
vector<float> reach_dists;

int main()
{
    pq seeds(CompareReachDist(&reach_dists));
    bool isEmpty = seeds.empty();

  return 0;
}

但是,在编译时出现错误:

error: request for member 'empty' in 'seeds', which is of non-class type 'pq(CompareReachDist&) {aka std::priority_queue<unsigned int std::vector<unsigned int>, CompareReachDist>(CompareReachDist&)}'

我哪里错了?

【问题讨论】:

    标签: c++ syntax initialization most-vexing-parse variable-initialization


    【解决方案1】:

    这是一个解析问题。让我们把它分开:

    CompareReachDist(&reach_dists)
    

    您可能会认为这会创建一个临时的CompareReachDist,其地址为静态reach_dists。但在整体声明的上下文中,它被解释为对CompareReachDist 的引用。奇怪,但这是因为,粗略地说,C++ 的语法偏向于函数声明而不是对象声明。以下

    pq seeds(CompareReachDist(&reach_dists));
    

    是一个函数的整体声明。它接受CompareReachDist&amp; 并返回pq。

    您收到的错误很明显是因为函数没有您可以调用的empty 成员。

    自 C++11 以来的解决方案是支持列表初始化,这打破了歧义及其作为函数声明的解析。所以你可以这样做:

    pq seeds{CompareReachDist{&reach_dists}};
    

    并得到一个对象,正如人们所期望的那样。

    【讨论】:

    • 啊,是的。我现在看到了。您认为我应该如何重构我的对象声明,以便编译器不再将其作为函数声明?
    • @ameya.dubey - 好吧,更喜欢 C++11 初始化语法。或者为CompareReachDist 参数引入一个命名变量。
    • @ameya.dubey - 确实如此。很高兴能帮上忙。
    • @ameya.dubey 也许你想了解 C++11 初始化语法 here.
    • 天哪,使用 {} 而不是 () 真的让我大吃一惊。我在这里呆了一个下午
    猜你喜欢
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多