【问题标题】:C++ template class' inner class accessC++ 模板类的内部类访问
【发布时间】:2020-05-18 08:05:31
【问题描述】:

我有这样的课:

#include <iostream>

template <class T>
class LL
{
    using size_t = unsigned int;

    class Node
    {
        T m_data;
        Node* m_next;

        Node(const T& data) :m_data{ data }, m_next{ nullptr }{}

        friend std::ostream& operator<<(std::ostream& out, const Node& node)
        {
            out << node.m_data;
            return out;
        }

        friend std::ostream& operator<<(std::ostream& out, const LL& ll);

        friend class LL;
    };

    Node* m_first{ nullptr };
    size_t m_size{ 0 };

    Node* newNode(const T& data)
    {
        return new Node{ data };
    }

public:
    void push(const T& data)
    {
        Node* temp = newNode(data);
        temp->m_next = m_first;
        m_first = temp;
        ++m_size;
    }

    Node* head()
    {
        return m_first;
    }

    size_t size() const
    {
        return m_size;
    }

    ~LL()
    {
        if (m_first)
        {
            Node* trav = m_first->m_next;
            Node* foll = m_first;
            while (trav)
            {
                delete foll;
                foll = trav;
                trav = trav->m_next;
            }
            delete foll;
        }
    }

    friend std::ostream& operator<<(std::ostream& out, const LL& ll)
    {
        Node* trav = ll.m_first;
        while (trav)
        {
            out << *trav << ' ';
            trav = trav->m_next;
        }
        return out;
    }
};

我在同一个文件中这个类下面的其他地方还有一个函数模板,它试图访问Node,看起来像这样,有两个编译器错误:

template <typename T>
int getSize(LL<T>::Node* node) //C2065: node is undeclared, C3861: node is not found
{
    if (node)
    {
        return 1 + getSize(node->m_next);
    }
    return 0;
} //does not compile

一段时间后我尝试了这个,再次使用两个编译器:

template <typename T>
int getSize(LL<T>::Node<T>* node) //C2065 like before, C7510: use of dependent template name must be prefixed with 'template'
{
    if (node)
    {
        return 1 + getSize(node->m_next);
    }
    return 0;
} //does not compile

又过了一段时间,我尝试了以下编译好的。

template <typename T>
int getSize(typename LL<T>::template Node<T>* node)
{
    if (node)
    {
        return 1 + getSize(node->m_next);
    }
    return 0;
}

现在,当我尝试从我的驱动程序函数中调用此函数时,我再次遇到编译器错误:

int main()
{
    LL<int> ll;
    std::cout << getSize(ll.head()); //E0304, C2672 and C2783

    //E0304: no instance of the function template "getSize" matches the argument list
    //C2672: no matching overload function found
    //C2783: could not deduce template argument for 'T'
}

我尽我所能,但无法解决这个问题。有人可以解释一下发生了什么吗? 注意:我在这里提到的所有代码都在同一个文件中。

【问题讨论】:

  • 请提供minimal reproducible example。您将声明/定义放在哪里?你有必要的包含吗?
  • Node 是私人的是故意的吗?
  • @idclev463035818 我已经更新以显示整个代码
  • 抱歉,mcve 不是“发布所有代码”的意思。缺少的信息就是定义的位置。没关系,结果已经足够诊断问题了

标签: c++ templates function-templates


【解决方案1】:

getSize(ll.head())non-deduced context 而失败;模板参数T不能自动推导出来。

如果模板参数仅用于非推导上下文且未明确指定,则模板参数推导失败。

  • 1) 使用限定 ID 指定的类型的嵌套名称说明符(范围解析运算符 :: 左侧的所有内容):

声明应该是

template <typename T>
int getSize(typename LL<T>::Node* node) // using class instead of typename works for OP (MSVC)
{
    //some code
}

由于Node 不是模板,因此您不需要使用template 关键字。

LIVE


请参阅Where and why do I have to put the “template” and “typename” keywords?,了解为什么使用关键字typenametemplate

【讨论】:

  • 但这仍然不应该工作,因为LL&lt;T&gt;::Nodeprivate
  • @t.niese - 当Node 是私有的时,它可以正常工作,稍作调整。
  • 因为 typename LL&lt;T&gt;::Node 由于 private 而无法工作,但像 template &lt;typename T&gt; int getSize(T* node)getSize(ll.head()) 这样的东西会工作。
  • @songyuanyao - 不,直接访问该名称应该是不可能的。但是该函数仍然可以定义为采用节点指针,例如template &lt;typename T&gt; int getSize(decltype(std::declval&lt;LL&lt;T&gt;&gt;().head()) node)
  • @AbhishekAUdupa 我可能只是 MSVC 的问题。
猜你喜欢
  • 2011-08-26
  • 2018-11-28
  • 1970-01-01
  • 2016-05-16
  • 1970-01-01
  • 2017-05-31
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
相关资源
最近更新 更多