Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 自;这";关键字在c+中通常是不必要的,并且被省略+;,为什么在本例中需要它?_C++_Templates - Fatal编程技术网

C++ 自;这";关键字在c+中通常是不必要的,并且被省略+;,为什么在本例中需要它?

C++ 自;这";关键字在c+中通常是不必要的,并且被省略+;,为什么在本例中需要它?,c++,templates,C++,Templates,我正在尝试实现优先级队列。这是接口类的代码: template<typename TYPE, typename COMP_FUNCTOR = std::less<TYPE>> class priority_queue { public: typedef unsigned size_type; virtual ~priority_queue() {} // impleted but does nothing, this is not a pure v

我正在尝试实现优先级队列。这是接口类的代码:

template<typename TYPE, typename COMP_FUNCTOR = std::less<TYPE>>
class priority_queue {
public:
    typedef unsigned size_type;

    virtual ~priority_queue() {}    // impleted but does nothing, this is not a pure virtual function

    virtual void fix() = 0;

    /* some other methods*/

protected:
    COMP_FUNCTOR compare;

};
模板
类优先级队列{
公众:
typedef无符号大小\u类型;
virtual~priority_queue(){}//已实现,但不执行任何操作,这不是纯虚拟函数
虚空修复()=0;
/*其他一些方法*/
受保护的:
COMP_函子比较;
};
以及导致问题的代码:

template<typename TYPE, typename COMP_FUNCTOR = std::less<TYPE>>
class sorted_priority_queue : public priority_queue<TYPE, COMP_FUNCTOR> {
public:
    typedef unsigned size_type;

    template<typename InputIterator>
    sorted_priority_queue(InputIterator start, InputIterator end, COMP_FUNCTOR comp = COMP_FUNCTOR());

    /* some other methods*/

private:
    std::vector<TYPE> data;
};

template<typename TYPE, typename COMP_FUNCTOR>
template<typename InputIterator>
sorted_priority_queue<TYPE, COMP_FUNCTOR>::sorted_priority_queue(
    InputIterator start, InputIterator end, COMP_FUNCTOR comp) {
    for(auto it = start; it != end; ++it) {
        data.push_back(*it);
    }
    fix();
    this->compare = comp;  // <--- the line that causes problem
}
模板
类排序的\u优先级\u队列:公共优先级\u队列{
公众:
typedef无符号大小\u类型;
模板
排序的\u优先级\u队列(输入计算器开始,输入计算器结束,COMP\u函子COMP=COMP\u函子());
/*其他一些方法*/
私人:
std::矢量数据;
};
模板
模板
排序的优先级队列::排序的优先级队列(
输入计算器开始,输入计算器结束,COMP_函子COMP){
用于(自动it=开始;it!=结束;++it){
数据。推回(*it);
}
fix();

这个->比较= COMP;//为了访问比较,这是接口类中定义的受保护成员变量,为什么?谢谢。

< P>这与C++模板类中如何执行名称查找有关。实际机制有点棘手,但本质上,当编译器首先看到模板类时,它试图解析所有O。在这种情况下,这意味着当它看到名称
compare
在没有
this->
前缀的情况下使用时,编译器希望
compare
指的是在没有任何模板参数先验知识的情况下可以找到的内容。不幸的是,在您的情况下编译器无法在不知道模板参数的情况下找出
compare
引用的内容,因为
compare
存储在基类中,这取决于模板参数。因此,当试图找出
compare
引用的内容时,它不会查看基类内部,因此会出现错误

另一方面,如果显式编写
this->compare
,编译器知道
compare
是类的一个成员,并将推迟查找它引用的名称,直到模板参数实际可用为止

这是语言中出现此类错误的少数情况之一,如果您正在访问

  • 基类中的一些东西
  • 在模板类中
  • 根据模板参数从某个对象继承的

  • 那么你需要使用<代码> -> <代码>前缀来避免这个问题。

    因为依赖名和两阶段查找。一开始是说这听起来是一个糟糕的编译器实现或差的模板设计标准。但是,我从来没有编写过C++编译器……或者C++设计标准。根据规范,这实际上是必需的。事实上,糟糕的编译器才是不能正确执行此操作的编译器。我怀疑规范以这种方式执行操作的原因是让一次性编译器在解析过程中构建尽可能多的AST,然后根据需要返回填充类型,而不必重新分析代码如果是这样,这是“C++支持一次编译”和“C++有模板”的必然结果这是最好的折衷办法。哦,我同意。我只是从一个天真的角度说了这句话。顺便说一句,你也可以使用
    使用
    语句使名称依赖于模板参数。这可能比使用
    这个->
    @templatetypedef更容易接受。谢谢,这非常有用帮助