![](/img/trans.png)
[英]error: there are no arguments to 'at' that depend on a template parameter, so a declaration of at must be available
[英]There are no arguments that depend on a template parameter
我正在嘗試執行以下操作:
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(...);
錯誤消息是這樣出現的,因為在模板中,您還可以輸入從屬名稱和兩階段查找的領域 。 依賴於模板參數的名稱,例如
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模型(C#)和懶惰模型(一些舊的C ++編譯器)。
TL; DR:用this-> ignore()替換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(){}
};
在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(){}
};
這意味着編譯器無法找到ignore
,並且ADL無法啟動。這意味着沒有適當范圍的ignore
函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.