【问题标题】:Function returning <error-type> instead of the intended raw pointer to a template class in C++函数返回 <error-type> 而不是指向 C++ 中模板类的预期原始指针
【发布时间】:2020-04-08 15:48:48
【问题描述】:

我在模板类中使用 first_ 变量时遇到问题(如下所示)。

template<typename T> class enable_movable_ptr {
public:
    //default constructor
    enable_movable_ptr() : ptr_(nullptr) {};
    enable_movable_ptr(T* p) : ptr_(p) {};

    //...
    //other constructors and operators
    //...

    T* get() {return ptr_; };
    movable_ptr<T>* First() { return first_; };
private:
    T* ptr_;
    movable_ptr<T>* first_ = nullptr;
};

template<typename T> class movable_ptr {
public:
    //Parameterless constructor
    movable_ptr() : trg_(nullptr) {};

    //Constructor from T*
    movable_ptr(T* p) : trg_(p) { add_to_tracked(this); };

    //...
    //other constructors and operators
    //...

    //access to variables
    enable_movable_ptr<T>* get() {return trg_; };
    movable_ptr<T>* Next(enable_movable_ptr<T>& p) {return next_; };
    movable_ptr<T>* Previous(enable_movable_ptr<T>& p) {return prev_; };

    //get_movable
    movable_ptr<T>* get_movable(enable_movable_ptr<T>& p) {};
private:
    enable_movable_ptr<T>* trg_;
    movable_ptr<T>* next_ = nullptr;
    movable_ptr<T>* prev_ = nullptr;
};

template<typename T> movable_ptr<T> get_movable(enable_movable_ptr<T>& p){
    if (p.First() != nullptr)
    {}
};

问题是,返回的first_ 属于&lt;error-type&gt; 类型(如果我将鼠标悬停在代码中的任何first_First() 上,它就会显示,除了VS2019 中的声明),而不是预期的movable_ptr&lt;T&gt;*。但是,如果我将鼠标悬停在 first_ 的声明上,它会显示正确的 movable_ptr&lt;T&gt;* 类型。

在我看来,编译器似乎拥有金鱼的记忆力,即使仍在同一个类定义中,也会忘记类型是什么。很可能不是这种情况,我怀疑是我做错了什么导致了这种情况。

关于我哪里出错或如何解决问题的任何想法?

【问题讨论】:

  • 当您“鼠标悬停”某些东西时,您似乎非常信任 IDE 向您显示的内容。不。充其量将其视为“有用的提示/猜测”。
  • 如果这是您的代码的确切顺序,那么当您声明 template&lt;typename T&gt; class enable_movable_ptr 时,movable_ptr 尚不为人所知。编译器的内存很好,但它是从上到下读取的。 ;-)
  • 是的,现在我看得很清楚了。在处理细节时忘记基础可能会导致问题,谁会猜到:D

标签: c++ pointers templates


【解决方案1】:

在定义enable_movable_ptr之前,只需转发声明movable_ptr

template<typename T> class movable_ptr;

否则,编译器甚至不知道movable_ptr 是一个可能存在的东西。

此外,最好不要依赖外部工具(例如您的 IDE)来告诉您代码有什么问题。让编译器这样做;它很可能对您的代码了解更多。

这就是问题的真正来源(我已经删除了所有与您的特定问题无关的代码)

// you need to forward declare
template <typename T> struct movable_ptr;

template <typename T> struct enable_movable_ptr {
  movable_ptr<T>* first_ = nullptr;  // else compiler won't know what movable_ptr is
};

template <typename T> struct movable_ptr {  
  enable_movable_ptr<T>* trg_;
};

这是mcve的链接。

【讨论】:

  • @Scheff 这是个好主意,谢谢。我添加了您的示例,但稍作修改。
猜你喜欢
  • 2011-08-02
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 2016-10-18
  • 2011-12-09
  • 1970-01-01
  • 2020-07-22
  • 1970-01-01
相关资源
最近更新 更多