没有依赖于模板参数的参数

我正在尝试执行以下操作:

template <class T> std::ifstream& operator>> (std::ifstream& fin, List<T> l) { T temp; l.resize(0); fin >> ignore(1,'\t'); for(ListIterator<T> i=l.begin();i!=l.end();i++) { fin >> ignore(1,'\t') >> temp; l.push_back(temp); } return fin; } 

我必须从文件中读取所有内容。 每个字段用'\t'字符分隔,所以我必须忽略'\t'字符。

错误日志如下:

 /home/ramy/Documents/C++/Prova/Util.h||In function 'std::ifstream& Util::operator>> (std::ifstream&, Util::List<T>)':| /home/ramy/Documents/C++/Prova/Util.h|431|error: there are no arguments to 'ignore' that depend on a template parameter, so a declaration of 'ignore' must be available| /home/ramy/Documents/C++/Prova/Util.h|431|note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)| ||=== Build finished: 1 errors, 0 warnings ===| 

对于内buildtypes,不执行依赖于参数的查找(ADL) ,因此, ignore符号必须“导入”到当前名称空间中。

例如,你可以这样做; 从最优选到最不优选(即最侵入性和污染名称):

  • foobar::ignore (...)
  • using foobar::ignore; ignore(...);
  • using namespace foobar; ignore(...);

这样的错误消息就会出现,因为在模板中,您还input相关名称和双向查找的领域 。 依赖于模板参数的名称,例如

 template <typename T> void foo() { T x; x.frobnicate(); } 

在实例化的阶段2中查找。 不依赖于模板参数的名称

 class Foo {}; template <typename T> void foo() { Foo foo; foo.frobnicate(); } 

必须在第一阶段解决。

这种分离有助于模板作者更早地发现错误并find正确的符号,这有助于使模板更通用。 例如,在C#generics中,所有东西都必须是可parsing的,这就使得它们的灵活性受到了相当严格的限制(因为所有可能被generics使用的东西都必须被定义)。 相反,一些旧的C ++编译器仅在阶段2解决,即在实例化时,这对于查找和错误发现具有一些微妙的结果。

C ++ 2阶段模型结合了最好的渴望模型(C#)和懒惰模型(一些旧的C ++编译器)。

有关更简单的答案,请参阅https://web.archive.org/web/20130423054841/http://www.agapow.net/programming/cpp/no-arguments-that-depend-on-a-template-parameter

TL; DR:用this-> ignore()replaceignore(),你的问题就会消失。

错误消息意味着编译器此时可以使用的没有ignore定义。 如果你这样做的话,你会得到同样的错误:

 void f() { g(); } void g() {} 

即使它看起来非常不同 请注意,这里没有ADL的问题,因为其他答案说。 错误信息如此复杂的原因是由于编译器处理模板的方式。

模板在两个过程中被处理,在第一次过程中,所有不依赖于实例化types的东西都必须被validation, 而不执行typesreplace ,在这个过程中,每个非从属名称都必须被检查,在这种情况下,编译器不能用模板定义处提供的声明来解决ignore

如果expression式依赖于模板的types参数,则不需要在第一次传递期间完全parsing,而是typesreplace之后再次尝试,并且在实例化处可用声明。

我遇到了同样的问题,并通过更改包含顺序来解决问题。

正如phresnel所说的,编译器无法解决第一阶段的问题,在我的情况下,这是因为带有问题模板方法的头包含在无法parsing的内部方法之前。

添加所需的标题包括为我删除了错误。 希望这可以帮助别人。

这意味着编译器无法findignore ,并且ADL无法启动。这意味着没有合适的范围ignorefunction。

我不知道你的问题得到解决的天气,我希望它会有。

每当我面临“没有依赖于模板参数的参数”的问题时,我重写该方法并调用父类成员函数。

为了展示我的意思是考虑一个类下面是模板类ADT

 template <typename DataTypeOfNode> class LinearList { public: LinearList(){} void addAtBeg(DataTypeOfNode data) { //Inside implementation.... } DataTypeOfNode removeFromFront() { //Inside implementation.... } // And many more useful methods ~LinearList(){} }; 

现在,如果你inheritance这个基类的类,像这样说“PriorityQueue”

 template <typename DataTypeOfNode> class PriorityQueue : public LinearList<DataTypeOfNode> { public: void enqueue(DataTypeOfNode data){ addAtBeg(data); } DataTypeOfNode dequeue(){ return removeFromFront() ; } PriorityQueue(){} ~PriorityQueue(){} }; 

compliling后,你会得到像“有没有依赖于模板参数的参数”removeFromFront()addAtBeg()方法,因为他们有模板参数的错误。

要解决这个错误,你只需要重写这些方法并像这样调用父类的方法

 template <typename DataTypeOfNode> class PriorityQueue : public LinearList<DataTypeOfNode> { public: //Calling parent class methods void addAtBeg(DataTypeOfNode data){ LinearList<DataTypeOfNode>::addAtBeg(data) ; } DataTypeOfNode removeFromFront(){ return LinearList<DataTypeOfNode>::removeFromFront() ; } void enqueue(DataTypeOfNode data){ addAtBeg(data); } DataTypeOfNode dequeue(){ return removeFromFront() ; } PriorityQueue(){} ~PriorityQueue(){} };