compilation error related to template parameter

S

subramanian100in

Consider the following program:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

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

Vec(int s) : vector<T>(s) { }

T& operator[] (int i) { return at(i); }
};

int main()
{
Vec<string> s(3);

return 0;
}

Suppose this program is named as y.cpp

When this program is compiled under Redhat Enterprise Linux
Workstation, as
g++ -std=c++98 -pedantic -Wall -Wextra y.cpp

I am getting the following compilation error:

y.cpp: In member function `T& Vec<T>::eek:perator[](int)':
y.cpp:14: error: there are no arguments to `at' that depend on a
template parameter, so a declaration of `at' must be available

However under VC++ Express Edition 2005, it compiles well without any
warning or error.

Kindly explain what is wrong with the above program and help me in
fixing the compilation error with g++ under Linux
 
R

red floyd

Consider the following program:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

template<class T> class Vec : public vector<T>
generally not a good idea. vector is not intended for inheritance.
{
public:
Vec() : vector<T>() { }

Vec(int s) : vector<T>(s) { }

T& operator[] (int i) { return at(i); }

T& operator[](int i) { return this->at(i); }
};

int main()
{
Vec<string> s(3);

return 0;
}
y.cpp: In member function `T& Vec<T>::eek:perator[](int)':
y.cpp:14: error: there are no arguments to `at' that depend on a
template parameter, so a declaration of `at' must be available


See FAQ 35.19:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19
 
G

Gianni Mariani

red said:
generally not a good idea. vector is not intended for inheritance.

Tell me this is not another - "need virtual destructor so you can't
inherit" - argument. If it is, you will find it's not a position of
consensus.
{
public:
Vec() : vector<T>() { }

Vec(int s) : vector<T>(s) { }

T& operator[] (int i) { return at(i); }

T& operator[](int i) { return this->at(i); }
};

int main()
{
Vec<string> s(3);

return 0;
}
y.cpp: In member function `T& Vec<T>::eek:perator[](int)':
y.cpp:14: error: there are no arguments to `at' that depend on a
template parameter, so a declaration of `at' must be available


See FAQ 35.19:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19
 
A

Alf P. Steinbach

* (e-mail address removed), India:
Consider the following program:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

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

Vec(int s) : vector<T>(s) { }

T& operator[] (int i) { return at(i); }
};

int main()
{
Vec<string> s(3);

return 0;
}

Suppose this program is named as y.cpp

When this program is compiled under Redhat Enterprise Linux
Workstation, as
g++ -std=c++98 -pedantic -Wall -Wextra y.cpp

I am getting the following compilation error:

y.cpp: In member function `T& Vec<T>::eek:perator[](int)':
y.cpp:14: error: there are no arguments to `at' that depend on a
template parameter, so a declaration of `at' must be available

However under VC++ Express Edition 2005, it compiles well without any
warning or error.

Kindly explain what is wrong with the above program and help me in
fixing the compilation error with g++ under Linux

As an alternative to Red Floyd's suggestion (else-thread) of

this->at( i )

you can add in the class

using vector<T>::at;

For the compiler needs to be informed -- somehow -- that "at" is meant
to be assumed to be a member function of vector<T>. Because whether it
is or not depends on T, which is unknown during the first pass through
the template definition. For example, "at" could be a global function.

<speculation>
I always find the explanation I gave above to be lacking, but it is the
one usually offered. It's a bit lacking because before two-phase
template instantiation was standardized, compilers managed code such as
above very well thank you, as evidently Visual C++ still does, without
needing to be informed about anything. A more Real(TM) reason why it
matters could be that "export" needs a context-independent template
definition (that could also help explain why "export" is so unpopular,
only officially supported by Comeau).
</speculation>
 
P

Premal

Consider the following program:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

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

Vec(int s) : vector<T>(s) { }

T& operator[] (int i) { return at(i); }

};

int main()
{
Vec<string> s(3);

return 0;

}

Suppose this program is named as y.cpp

When this program is compiled under Redhat Enterprise Linux
Workstation, as
g++ -std=c++98 -pedantic -Wall -Wextra y.cpp

I am getting the following compilation error:

y.cpp: In member function `T& Vec<T>::eek:perator[](int)':
y.cpp:14: error: there are no arguments to `at' that depend on a
template parameter, so a declaration of `at' must be available

However under VC++ Express Edition 2005, it compiles well without any
warning or error.

Kindly explain what is wrong with the above program and help me in
fixing the compilation error with g++ under Linux

Hi,
you can try following one:
rather than using return at(i) use the following one:
return vector<T>::at(i)
 
V

Victor Bazarov

Consider the following program:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

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

Vec(int s) : vector<T>(s) { }

T& operator[] (int i) { return at(i); }
};

int main()
{
Vec<string> s(3);

return 0;
}

Suppose this program is named as y.cpp

When this program is compiled under Redhat Enterprise Linux
Workstation, as
g++ -std=c++98 -pedantic -Wall -Wextra y.cpp

I am getting the following compilation error:

y.cpp: In member function `T& Vec<T>::eek:perator[](int)':
y.cpp:14: error: there are no arguments to `at' that depend on a
template parameter, so a declaration of `at' must be available

However under VC++ Express Edition 2005, it compiles well without any
warning or error.

Kindly explain what is wrong with the above program and help me in
fixing the compilation error with g++ under Linux

My newsserver is slow today, so I may be replying to something that
has already been discussed, sorry for that.

In your case 'at' is a dependent name. You need to help the compiler
to find it by pointing it to the member function. There are two ways
to do that, a 'using' declaration and an explicit qualification of
the name. So, either do

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

Vec(int s) : vector<T>(s) { }

T& operator[] (int i) { return at(i); }
};

or


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

Vec(int s) : vector<T>(s) { }

T& operator[] (int i) { return this->at(i); }
// or
// T& operator[] (int i) { return vector<T>->at(i); }
};

Next time read the FAQ first.

V
 
J

James Kanze

Tell me this is not another - "need virtual destructor so you can't
inherit" - argument. If it is, you will find it's not a position of
consensus.

It's probably more simply a case of "using a class in ways it
was not designed for doesn't work". A fact of life. (But there
are always amateur hackers who try to ignore it.)
 
V

Victor Bazarov

James said:
It's probably more simply a case of "using a class in ways it
was not designed for doesn't work". A fact of life. (But there
are always amateur hackers who try to ignore it.)

It's probably another attempt to impose a style (coding or design)
ridden with undue limitations. Condescending tone does make one
look/sound important, no doubt.

Search the archives for "standard containers are not intended to be
derived from" and make your own conclusions, that's what I say.

V
 
J

James Kanze

* (e-mail address removed), India:


Consider the following program:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
template<class T> class Vec : public vector<T>
{
public:
Vec() : vector<T>() { }
Vec(int s) : vector<T>(s) { }
T& operator[] (int i) { return at(i); }
};
int main()
{
Vec<string> s(3);
return 0;
}
Suppose this program is named as y.cpp
When this program is compiled under Redhat Enterprise Linux
Workstation, as
g++ -std=c++98 -pedantic -Wall -Wextra y.cpp
I am getting the following compilation error:
y.cpp: In member function `T& Vec<T>::eek:perator[](int)':
y.cpp:14: error: there are no arguments to `at' that depend on a
template parameter, so a declaration of `at' must be available
However under VC++ Express Edition 2005, it compiles well without any
warning or error.
Kindly explain what is wrong with the above program and help me in
fixing the compilation error with g++ under Linux

As an alternative to Red Floyd's suggestion (else-thread) of

this->at( i )

you can add in the class

using vector<T>::at;

For the compiler needs to be informed -- somehow -- that "at" is meant
to be assumed to be a member function of vector<T>. Because whether it
is or not depends on T, which is unknown during the first pass through
the template definition. For example, "at" could be a global function.

<speculation>
I always find the explanation I gave above to be lacking, but it is the
one usually offered. It's a bit lacking because before two-phase
template instantiation was standardized, compilers managed code such as
above very well thank you, as evidently Visual C++ still does, without
needing to be informed about anything. A more Real(TM) reason why it
matters could be that "export" needs a context-independent template
definition (that could also help explain why "export" is so unpopular,
only officially supported by Comeau).
</speculation>

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
B

Bo Persson

Alf P. Steinbach wrote:
::
:: For the compiler needs to be informed -- somehow -- that "at" is
:: meant to be assumed to be a member function of vector<T>. Because
:: whether it is or not depends on T, which is unknown during the
:: first pass through the template definition. For example, "at"
:: could be a global function.
::
:: <speculation>
:: I always find the explanation I gave above to be lacking, but it
:: is the one usually offered. It's a bit lacking because before
:: two-phase template instantiation was standardized, compilers
:: managed code such as above very well thank you, as evidently
:: Visual C++ still does, without needing to be informed about
:: anything. A more Real(TM) reason why it matters could be that
:: "export" needs a context-independent template definition (that
:: could also help explain why "export" is so unpopular, only
:: officially supported by Comeau). </speculation>
::

It doesn't really work, it just pretends. Note that the OP used
"-std=c++98 -pedantic" with g++. That is definitely not the default
setting for VC++.

As you certainly know, in "compatibility mode" VC++ will pick whatever
it finds at instantiation time, a vector<mytype>::at() or some other
visible at() function, or just fail if none is present. I think this
is an ODR violation in disguise.

Isn't it better to fix the problem up front with the original
template, and not wait for the third case (or debug case two for a
month)?


Bo Persson
 
A

Alf P. Steinbach

* Bo Persson:
Alf P. Steinbach wrote:
::
:: For the compiler needs to be informed -- somehow -- that "at" is
:: meant to be assumed to be a member function of vector<T>. Because
:: whether it is or not depends on T, which is unknown during the
:: first pass through the template definition. For example, "at"
:: could be a global function.
::
:: <speculation>
:: I always find the explanation I gave above to be lacking, but it
:: is the one usually offered. It's a bit lacking because before
:: two-phase template instantiation was standardized, compilers
:: managed code such as above very well thank you, as evidently
:: Visual C++ still does, without needing to be informed about
:: anything. A more Real(TM) reason why it matters could be that
:: "export" needs a context-independent template definition (that
:: could also help explain why "export" is so unpopular, only
:: officially supported by Comeau). </speculation>
::

It doesn't really work, it just pretends.
Yes.


Note that the OP used
"-std=c++98 -pedantic" with g++. That is definitely not the default
setting for VC++.

As you certainly know, in "compatibility mode" VC++ will pick whatever
it finds at instantiation time, a vector<mytype>::at() or some other
visible at() function, or just fail if none is present. I think this
is an ODR violation in disguise.

Isn't it better to fix the problem up front with the original
template, and not wait for the third case (or debug case two for a
month)?

Assuming you think I've argued that the pre-standard behavior was more
practical than the current standard behavior: no, I didn't argue that,
but yes, since you seem to mention it, I do think it was better because
it made the most common case require no extra typing, i.e. a reasonable
default, so that time spent fixing actual problems was, I think, less
than the time now required to prevent in advance problems that probably
won't occur, fighting the compiler instead of one's own bugs (which are
preventable). But having been weaned on Pascal and Modula-2 I also
agree with you that strong type checking and context-independence for
meaning of a definition is Good(TM), /when it's done right/. It's just
that the current rules as I see it don't do it right.

The current rules have it backwards. They require some extra indication
that "yes, I really mean to use a class member here". At least for
other than unqualified type names it would be much more sensible to
require an extra indication that "nope, this here ain't no class member,
I'm using something global", and for a standard-conforming compiler get
a diagnostic if such indication is not present and no corresponding
class member is found on instantiation.

But hey, it's like most of the defaults in C++ are backwards, by
historical accident.
 
B

BobR

Victor Bazarov said:
My newsserver is slow today,

I've noticed that too. I wonder if it has anything to do with dictator
bush's plan to monitor everything going into/out_of the U.S.A.. (that seems
to be about when it started.)
 
V

Victor Bazarov

BobR said:
I've noticed that too. I wonder if it has anything to do with dictator
bush's plan to monitor everything going into/out_of the U.S.A.. (that
seems to be about when it started.)

<shrug> Then I'd see slowness on other sources as well, and I didn't.

V
 
A

Alf P. Steinbach

* Victor Bazarov:
<shrug> Then I'd see slowness on other sources as well, and I didn't.

<url: http://news.yahoo.com/s/ap/20070816/ap_on_hi_te/germany_skype_outage>

<q>
Skype, the popular computer program that lets its users make
long-distance phone calls over the Internet, said Thursday that software
problems have left many of its millions of users without service worldwide
</q>

:)


Of course this is very off-topic, but more seriously (in the interest of
correcting impression made by the article I'm responding to) see also
<url: http://www.csmonitor.com/2007/0806/p99s04-duts.html>:

<q>
Second, Bush has said his original surveillance program was restricted
to calls and e-mails involving a suspected terrorist, but the new law
has no such limit. Instead, it allows executive-branch agencies to
conduct oversight-free surveillance of all international calls and
e-mails, including those with Americans on the line, with the sole
requirement that the intelligence-gathering is "directed at a person
reasonably believed to be located outside the United States." There is
no requirement that either caller be a suspected terrorist, spy, or
criminal.
</q>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top