Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates_Visual C++_Dependent Name - Fatal编程技术网

C++ 嵌套的模板类和全局命名空间中的函数

C++ 嵌套的模板类和全局命名空间中的函数,c++,templates,visual-c++,dependent-name,C++,Templates,Visual C++,Dependent Name,我正在研究一个模板图数据结构,它是GraphNode对象的STL向量。我定义了嵌套在Graph类中的GraphNode类,当我在Graph对象Visual Studio 15(C++)报告的重载插入操作符中调用GraphNode对象的重载插入操作符时 (30):警告C4346:'myGraph::myGraphNode':依赖名称不是类型 (30):注:前缀为“typename”表示类型 (30):错误C2061:语法错误:标识符“myGraphNode” (33):错误C2805:二进制运算符

我正在研究一个模板图数据结构,它是GraphNode对象的STL向量。我定义了嵌套在Graph类中的GraphNode类,当我在Graph对象Visual Studio 15(C++)报告的重载插入操作符中调用GraphNode对象的重载插入操作符时

(30):警告C4346:'myGraph::myGraphNode':依赖名称不是类型
(30):注:前缀为“typename”表示类型
(30):错误C2061:语法错误:标识符“myGraphNode”

(33):错误C2805:二进制运算符首先,参数声明的正确语法应为

template <typename T>
ostream& operator<<(ostream& strm, const typename myGraph<T>::myGraphNode& gn)
//                                 ~~~~~ ~~~~~~~~

但是很难看。对于您的情况,您可以只实现
operator模板类型推断仅匹配模式。它不会反转依赖类型,因为(在一般情况下)这是不可能的

解决这个问题的方法是我称之为Koenig算子的技术

friend std::ostream& operator<<(std::ostream& strm, const myGraphNode& gn) {
  strm << gn.mData << std::endl;
  return strm;
}

这是一个注入周围名称空间(仅)的非模板运算符,可通过ADL访问。这是“it just works”的花哨词语。

问题源于这样一个事实,即当解析器遇到
myGraph::myGraphNode
时,由于
myGraph
是一个模板,所以它(通常)无法知道
myGraphNode
是否引用类型、对象,或者不预先为某些
T
实例化模板的其他内容。因此,决定将其解释为“默认”值,并且需要添加typename(如下所示:
typename myGraph::myGraphNode
)要显式地告诉解析器这是一种类型。谢谢,但我想重载myGraphNode对象的插入运算符,而不是让myGraph类了解myGraphNode实现。我知道有解决这个问题的办法,我想更好地理解这个问题。我试图在第一个回答的链接中遵循这一技巧,但似乎很难准确理解在我的具体案例中该做什么。谢谢你的解释和指导。谢谢。这个operator@studentProgrammer那么你在理解第一期杂志时仍然有困难?(即关于使用
typename
)@studentProgrammer第二期,据我所知,没有办法;您必须指定模板参数,如
operator。当我按照您的建议执行typename时,仍然会出现编译器错误。谢谢Yakk,这同样有效。我试图将函数的实现排除在定义之外,因为有些函数变得相当长。有没有可能把这项计划付诸实施operator@student转到另一种方法。像
void打印(std::ostream&)
template <typename T>
ostream& operator<<(ostream& strm, typename const myGraph<T>::myGraphNode& gn)
(49): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'const myGraph<int>::myGraphNode' (or there is no acceptable conversion)
#include <iostream>
#include <vector>
#include <string>

using namespace std;

typedef unsigned int uint;

template <typename T>
class myGraph {
public:
    class myGraphNode {
    public:
        myGraphNode(T val = T());
        T mData;
    }; // end class myGraphNode

    myGraph();

    uint addGraphNode(T data);
    vector<myGraphNode> mGraphNodes;
}; // end class myGraph


//          myGraphNode
template <typename T>
myGraph<T>::myGraphNode::myGraphNode(T val) : mData(val) {}

template <typename T>
ostream& operator<<(ostream& strm, typename const myGraph<T>::myGraphNode& gn) {
    strm << gn.mData << std::endl;
    return strm;
}


//          myGraph
template <typename T>
myGraph<T>::myGraph() {}

template <typename T>
uint myGraph<T>::addGraphNode(T data) {
    myGraph<T>::myGraphNode node(data);
    mGraphNodes.push_back(node);
}

template <typename T>
ostream& operator<<(ostream& strm, const myGraph<T>& g) {
    for (uint i = 0; i < g.mGraphNodes.size(); ++i)
        cout << g.mGraphNodes[i] << endl;
    return strm;
} // end operator<<(...)

int main()
{
    myGraph<int> g;
    g.addGraphNode(3);
    g.addGraphNode(5);
    cout << g << endl;
    return 0;
}
template <typename T>
ostream& operator<<(ostream& strm, const typename myGraph<T>::myGraphNode& gn)
//                                 ~~~~~ ~~~~~~~~
operator<<<T>(strm, g.mGraphNodes[i]);
//        ~~~
template <typename T>
ostream& operator<<(ostream& strm, const myGraph<T>& g) {
    for (uint i = 0; i < g.mGraphNodes.size(); ++i)
        cout << g.mGraphNodes[i].mData << endl;
    return strm;
}
friend std::ostream& operator<<(std::ostream& strm, const myGraphNode& gn) {
  strm << gn.mData << std::endl;
  return strm;
}
class myGraphNode {
public:
    myGraphNode(T val = T());
    T mData;
    friend std::ostream& operator<<(std::ostream& strm, const myGraphNode& gn) {
      strm << gn.mData << std::endl;
      return strm;
    }
}; // end class myGraphNode