[Solved] error: there are no arguments to ‘at’ that depend on a template parameter, so a declaration of at must be available

Noob here,

I’m trying to compile this segment of code from Bjarne Stroustrup’s ‘The C++ Programming Language’ but CodeBlocks keeps throwing me this error.

The code is about range checking an array held in a vector function.

Here is the code:

#include <iostream>
#include <vector>
#include <array>

using namespace std;

int i = 1000;

template<class T> class Vec : public vector<T>
{
public:
    Vec() : vector<T>() { }

    T& operator[] (int i) {return at(i); }
    const T& operator[] (int i) const {return at(i); }
    //The at() operation is a vector subscript operation 
    //that throws an exception of type out_of_range
    //if its argument is out of the vector's range.
};

Vec<Entry> phone_book(1000);

int main()
{

    return 0;
}

The errors returned are:

  • there are no arguments to ‘at’ that depend on a template parameter, so a declaration of ‘at’ must be available
  • note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated
  • In member function ‘const T& operator[] (int i) const’:
  • there are no arguments to ‘at’ that depend on a template parameter, so a declaration of ‘at’ must be available
  • ‘Entry’ was not declared in this scope
  • template argument 1 is invalid
  • invalid type in declaration before ‘(‘ token

Can someone explain this to me?

Also, how would I implement this if I were to not use ‘using namespace std;’

Solution #1:

Replace at with vector<T>::at or this->at.

Rules for how functions are looked up in templates are tighter now than when C++ was being originally designed.

Now, methods in dependent bases are only looked up if you this->, otherwise it is assumed to be a global function (or a non-dependent base/class local/etc).

This can help avoid nasty surprises in practice, where what you thought was a method call becomes a global one, or a global call becomes a method call. It also allows earlier checking of template method bodies.

Solution #2:

In addition to Yakk’s answer, another solution would be to add

using vector<T>::at;

to Vec basically adding it to the list of looked up functions.

This way, at() can be used as usual without prefixing it with the base class type or this->.

Respondent: noma

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Leave a Reply

Your email address will not be published.