program story

템플릿 매개 변수에 의존하는 인수가 없습니다.

inputbox 2020. 12. 12. 10:42
반응형

템플릿 매개 변수에 의존하는 인수가 없습니다.


다음을 시도하고 있습니다.

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

내장 유형의 경우 인수 종속 조회 (ADL) 가 수행되지 않으므로 ignore기호는 현재 네임 스페이스로 "가져 오기"되어야합니다.

예를 들어 다음과 같이 할 수 있습니다. 가장 선호되는 것에서 가장 선호하지 않는 것 (즉, 가장 침입적이고 이름을 오염시키는 것) :

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

템플릿에서 종속 이름 및 Two Phase Lookup 의 영역도 입력하기 때문에 오류 메시지가 이와 같이 나타납니다 . 템플릿 매개 변수에 의존하는 이름, 예 :

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

인스턴스화되는 2 단계에서 조회됩니다. 다음과 같이 템플릿 매개 변수에 의존하지 않는 이름

class Foo {};

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

첫 번째 단계에서 해결 가능해야합니다.

이러한 분리는 템플릿 작성자가 버그를 더 일찍 발견하고 올바른 기호를 찾는 데 도움이되며 템플릿을보다 일반적으로 만드는 데 도움이됩니다. 예를 들어, C # 제네릭에서는 모든 것이 해결 가능해야하며, 이는 유연성에 다소 엄격한 제한을 둡니다 ( 제네릭에서 사용할 있는 모든 항목을 정의 해야하기 때문). 반대로 일부 오래된 C ++ 컴파일러는 2 단계에서만 해결되었습니다. 즉 인스턴스화 시간에 조회 및 오류 발견에 약간의 미묘한 결과가있었습니다.

C ++ 2 단계 모델은 최고의 eager-model (C #)과 lazy-model (일부 오래된 C ++ 컴파일러)을 결합합니다.


더 쉬운 답변은 https://web.archive.org/web/20130423054841/http://www.agapow.net/programming/cpp/no-arguments-that-depend-on-a-template-parameter를 참조 하세요.

요약 : ignore ()를 this-> ignore ()로 바꾸면 문제가 사라집니다.


오류 메시지는 ignore이 시점에서 컴파일러가 사용할 수있는 정의가 없음을 의미합니다 . 다음과 같은 경우 발생하는 오류와 정확히 동일합니다.

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

... 아주 다르게 보일지라도 . 다른 답변에서 말하는 것처럼 여기에는 ADL 문제가 없습니다. 오류 메시지가 너무 복잡 해지는 이유는 컴파일러가 템플릿을 처리하는 방식 때문입니다.

템플릿은 두 단계로 처리됩니다. 첫 번째 단계에서는 인스턴스화 유형에 종속되지 않은 모든 항목을 유형 대체를 수행하지 않고 확인해야합니다. 이 단계에서는 모든 비 종속 이름을 확인해야합니다.이 경우 컴파일러가 실패했습니다. ignore템플릿 정의 위치에서 사용 가능한 선언으로 해결 합니다.

식이 템플릿에 대한 형식 인수에 종속 된 경우 첫 번째 패스 동안 완전히 해석 될 필요가 없으며 인스턴스화 위치에서 선언을 사용할 수있는 형식 대체 후에 다시 시도됩니다 .


나는 같은 문제가 있었고 포함 순서를 변경하여 수정했습니다.

phresnel이 말했듯이 컴파일러는 첫 번째 단계에서 해결할 수 없습니다. 제 경우에는 문제가있는 템플릿 메서드가있는 헤더가 해결할 수없는 내부 메서드가있는 헤더보다 먼저 포함 되었기 때문입니다.

필요한 헤더를 추가하면 오류가 제거되었습니다. 이것이 다른 사람에게 도움이되기를 바랍니다.


나는 당신의 문제가 해결되었는지의 날씨에 대해 알지 못합니다.

"템플릿 매개 변수에 의존하는 인수가 없습니다" 라는 문제에 직면 할 때마다 메서드를 재정의하고 부모 클래스 멤버 함수를 호출합니다.

내가 의미하는 바를 보여주기 위해 템플릿 클래스 ADT 인 클래스를 고려하십시오.

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

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

};

이제 기본 클래스로이 클래스를 상속하면 다음 과 같이 "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.

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

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

참고URL : https://stackoverflow.com/questions/9941987/there-are-no-arguments-that-depend-on-a-template-parameter

반응형