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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9941987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:25:02  来源:igfitidea点击:

There are no arguments that depend on a template parameter

c++templates

提问by Ramy Al Zuhouri

I am trying to do the following:

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

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;
}

I have to read all the contents from a file. Each field is separated by '\t'character, so I have to ignore the '\t'characters.

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

The error log is the following:

错误日志如下:

/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 ===|

采纳答案by Sebastian Mach

For builtin types, argument dependent lookup (ADL)is not performed, therefore, an ignoresymbol must be "imported" into the current namespace.

对于内置类型,不执行参数相关查找 (ADL),因此,ignore必须将符号“导入”到当前命名空间中。

You can, for example, do this; from most preferred to least preferred (i.e. to most intrusive and name polluting):

例如,您可以这样做;从最喜欢到最不喜欢(即到最具侵入性和名称污染):

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

The error message comes up like this because in templates, you also enter the realm of dependent names and Two Phase Lookup. Names that depend on a template parameter, e.g.

错误消息是这样出现的,因为在模板中,您还输入了相关名称和两阶段查找的领域。依赖于模板参数的名称,例如

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

are looked up in phase 2, which is upon instantiation. Names that do not depend on template parameters, like

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

class Foo {};

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

must be resolvable in the first phase.

必须在第一阶段解决。

This separation helps template authors to find bugs earlier and to find correct symbols, and it helps making templates more generic. For example, in C# generics, everything must be resolvable, which puts rather stringent limits on their flexibility (because everything that maybe used by a generic mustbe defined). Oppositely, some old C++ compilers resolved in phase 2 only, i.e. at instantiation time, which had some subtle consequences for lookup and error finding.

这种分离有助于模板作者更早地发现错误并找到正确的符号,并且有助于使模板更加通用。例如,在 C# 泛型中,一切都必须是可解析的,这对其灵活性施加了相当严格的限制(因为必须定义泛型可能使用的一切)。相反,一些旧的 C++ 编译器仅在第 2 阶段解决,即在实例化时,这对查找和错误查找有一些微妙的影响。

The C++ 2-phase model combines the best of the eager-model (C#) and the lazy-model (some old C++ compilers).

C++ 2 阶段模型结合了eager-model (C#) 和lazy-model(一些旧的C++ 编译器)的优点。

回答by John Hainsworth

For an easier answer, see https://web.archive.org/web/20130423054841/http://www.agapow.net/programming/cpp/no-arguments-that-depend-on-a-template-parameter

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

TL;DR: replace ignore() with this->ignore() and your problem will go away.

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

回答by David Rodríguez - dribeas

The error message means that there is no definition of ignorethat the compiler can use at this point. It is exactly the same error that you get if you do:

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

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

... even if it looks verydifferent. Note that there is no ADL issue here as the other answers say. The reason that the error message is so convoluted is because of the way that templates are processed by the compiler.

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

Templates are processed in two passes, during the first pass everything that is not dependent on the instantiating type must be verified without performing the type substitution, during this pass every non-dependent name must be checked, and in this case the compiler has failed to resolve ignorewith the declarations available at the place of definition of the template.

模板分两遍处理,在第一遍中,所有不依赖于实例化类型的都必须在不执行类型替换的情况下进行验证,在此遍中必须检查每个非依赖名称,在这种情况下编译器未能ignore使用模板定义处可用的声明进行解析。

If the expression depended on the type arguments to the template, it would not need to be fully resolved during the first pass and it would be tried again aftertype substitution, with the declarations available at the place of instantiation.

如果表达式依赖于模板的类型参数,则不需要在第一次传递期间完全解析它,并且会类型替换再次尝试,并在实例化位置使用声明。

回答by Xavier Arias Botargues

I've had the same problem and I've fixed it by changing include order.

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

As phresnel says, the compiler cannot resolve that on the 1st phase, which in my case was because the header with the problematic template method was included before the one with the inner method that couldn't be resolved.

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

Adding the needed header include removed the error for me. Hope this helps someone else.

添加所需的标头包括为我删除了错误。希望这对其他人有帮助。

回答by Mr. Suryaa Jha

I don't know about the weather your problem is solved or not and I hope it would have.

我不知道你的问题解决与否的天气,我希望它会解决。

Whenever I face the problem of "There are no arguments that depend on a template parameter"I override the method and call the parent class member function.

每当我遇到“没有依赖于模板参数的参数”的问题时,我都会覆盖该方法并调用父类成员函数。

To show what I mean consider a class below which is template class ADT

为了说明我的意思,请考虑下面的一个类,它是模板类 ADT

template <typename DataTypeOfNode>
class LinearList
{
public:
    LinearList(){}
    void addAtBeg(DataTypeOfNode data) {
        //Inside implementation....
    }
    DataTypeOfNode removeFromFront() {
        //Inside implementation....
    } 

    // And many more useful methods
    ~LinearList(){}

};

Now if you inherit this class with a base class say "PriorityQueue"like this

现在,如果您使用基类继承此类,请像这样说“PriorityQueue”

template <typename DataTypeOfNode>
class PriorityQueue : public LinearList<DataTypeOfNode>
{
public:

    void enqueue(DataTypeOfNode data){
        addAtBeg(data);
    }

    DataTypeOfNode dequeue(){
        return removeFromFront() ; 
    }
    PriorityQueue(){}
    ~PriorityQueue(){}
};

After compliling you will get error like "There are no arguments that depend on a template parameter"for removeFromFront()and addAtBeg()methods becaouse they have template parameters.

compliling你会得到错误,如后“有实参不依赖模板参数”removeFromFront()addAtBeg()方法becaouse他们有模板参数。

To fix this error you just need to override these methods and call the parent class methods like this

要修复此错误,您只需要覆盖这些方法并像这样调用父类方法

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(){}
};

回答by Puppy

It means that ignorecannot be found by the compiler and ADL cannot kick in. This means that there is no suitably-scoped ignorefunction.

这意味着ignore无法被编译器找到并且 ADL 无法启动。这意味着没有适当范围的ignore函数。