Page 1 of 1
C++ use of specialization and inheritance
Posted: Sun Aug 27, 2006 2:55 pm
by Candy
I'm fighting a bit with GCC on this, I would say it should work but GCC isn't accepting it.
My code more or less follows these lines:
Code: Select all
template <typename O>
class OT {};
class A{};
template <typename I, typename O>
class B : public A {
public:
OT<O> *obj;
};
template <typename O>
class B<void, O> : public A {
public:
OT<O> *obj;
};
template <typename O>
class C : public B<void, O> {
public:
function() {
obj->something();
}
};
The compiler is whining about the call to something on obj, claiming that it doesn't know obj. If I replace class C with:
Code: Select all
template <typename O>
class C : public B<void, O> {
public:
function() {
B<void, O>::obj->something();
}
};
it works.
Imo the compiler should accept the first, with the second being a resort in case of having two possible variables it could resolve to (with a warning of ambiguity with it). Am I wrong or is the GCC compiler wrong?
I'm using GCC version 3.4.6 compiled for x86, the one that's packaged with Slackware 10.2:
Configured with: ../gcc-3.4.6/configure --prefix=/usr --enable-shared --enable-threads=posix --enable-__cxa_atexit --disable-checking --with-gnu-ld --verbose --target=i486-slackware-linux --host=i486-slackware-linux
Thread model: posix
gcc version 3.4.6
Re:C++ use of specialization and inheritance
Posted: Wed Aug 30, 2006 2:08 pm
by bluecode
hi,
I tried to compile
Code: Select all
#include <iostream>
using namespace std;
template <typename O>
class OT
{
public:
void something(){cout << "hello" << endl;}
};
class A{};
template <typename I, typename O>
class B : public A {
public:
OT<O> *obj;
};
template <typename O>
class B<void, O> : public A {
public:
OT<O> *obj;
};
template <typename O>
class C : public B<void, O> {
public:
void function() {
obj->something();
}
};
int main()
{
C<int> c;
c.function();
}
There are no errors/warnings and it works as expected. I would also expect it to work without the scope operator. Perhaps your problem is something else? ??? Or did I change your example in some way?
On thing I could think of: template specialization only works from right to left parameter (afaik), but your specializing the first parameter.
[edit: mh, I might have gotten mixed up with default (template) parameters which must be from right to left... not sure. time to sleep
)
I used gcc 3.3.6 to compile.
Re:C++ use of specialization and inheritance
Posted: Thu Aug 31, 2006 12:03 pm
by Candy
No, that's pretty much my setup too. I'm wondering whether it's something that the GCC people don't test that might've been broken? Lemme compile it with a 4.1.? crosscompiler and see what it says. At least this provides me more confidence in my c++
Re:C++ use of specialization and inheritance
Posted: Thu Aug 31, 2006 12:17 pm
by bluecode
I'm currently emerging gcc 4.1.1. When it's done I will try to recompile this code and also post the results here.
Re:C++ use of specialization and inheritance
Posted: Thu Aug 31, 2006 12:54 pm
by Candy
bluecode wrote:
There are no errors/warnings and it works as expected. I would also expect it to work without the scope operator. Perhaps your problem is something else? ??? Or did I change your example in some way?
candy@blackbox:~/atlantisos/libaos/modules/randomnumber$ gcc -c -o test.o test.cc
test.cc: In member function `void C<O>::function()':
test.cc:29: error: `obj' was not declared in this scope
candy@blackbox:~/atlantisos/libaos/modules/randomnumber$
No, the basic problem is still in it. I tried to compile my own program with the gcc 4.* compiler but it complained I lacked string, typeinfo etc (which I'm borrowing from the GCC STL atm). Pointing it to the linux version increased my compile problems to more than 400 lines, so I think I'm going to create those libraries myself before testing it properly with the 64-bit cross compiler. Too bad though.
However:
candy@blackbox:~/atlantisos/libaos/modules/randomnumber$ /usr/amd64/bin/x86_64-pc-elf-gcc -c -o test.o test.cc
test.cc:1:20: error: iostream: No such file or directory
test.cc: In member function 'void OT<O>::something()':
test.cc:8: error: 'cout' was not declared in this scope
test.cc:8: error: 'endl' was not declared in this scope
test.cc: In member function 'void C<O>::function()':
test.cc:29: error: 'obj' was not declared in this scope
uh... strip that:
candy@blackbox:~/atlantisos/libaos/modules/randomnumber$ /usr/amd64/bin/x86_64-pc-elf-gcc -c -o test.o test.cc
test.cc: In member function 'void C<O>::function()':
test.cc:27: error: 'obj' was not declared in this scope
candy@blackbox:~/atlantisos/libaos/modules/randomnumber$
And that's with
candy@blackbox:~/atlantisos/libaos/modules/randomnumber$ /usr/amd64/bin/x86_64-pc-elf-gcc -v
Using built-in specs.
Target: x86_64-pc-elf
Configured with: ../gcc-4.1.1/configure --target=x86_64-pc-elf --prefix=/usr/amd64 --disable-nls --enable-languages=c,c++ --without-headers
Thread model: single
gcc version 4.1.1
candy@blackbox:~/atlantisos/libaos/modules/randomnumber$
I'm suspecting somebody introduced a bug without considering it or this was an intentional change to facilitate something else accidentally breaking my code. Could you post the gcc -v of your compiler?
Re:C++ use of specialization and inheritance
Posted: Fri Sep 01, 2006 12:54 pm
by Candy
This is a problem in GCC. I'm pretty certain this isn't my thinking.
Code: Select all
template <typename x>
class B {
public:
char *obj;
};
template <typename I, typename O>
class C : public B<I> {
public:
void function() {
obj;
}
};
This doesn't compile. Don't mind that it doesn't do anything.
Anyone know whether this is actually illegal or such?
Re:C++ use of specialization and inheritance
Posted: Fri Sep 01, 2006 1:01 pm
by Kemp
If I just drop that into a header for something I've already got in MSVC++ (not the most standard's compliant compiler I know) then it compiles fine, though I don't try to use the classes if that matters. What errors are you getting with that particular example? As far as I can see myself, that code should be valid.
Re:C++ use of specialization and inheritance
Posted: Fri Sep 01, 2006 1:53 pm
by bluecode
Candy wrote:This is a problem in GCC.
It's not.
Anyone know whether this is actually illegal or such?
It is illegal. translation of an answer from a german c++ forum:
The compiler does not search in dependend base classes when doing the unqualified lookup. It is not obvious, that obj is member of the base class B<void, O>. That can only be determined when instantiating. For the purpose of the namelookup it is completely irrelevant, whether a the base class template (or any specialisation) is already defined.
C++ forum thread
I hope that translation helped you
Re:C++ use of specialization and inheritance
Posted: Sat Sep 02, 2006 9:48 am
by Candy
bluecode wrote:
Candy wrote:This is a problem in GCC.
It's not.
Okay, that was a pretty fixed statement. I'm not sure whether it is good the way it is right now though, I think it should be clearer. In effect, this limits template-to-template inheritance to quite a lot less than normal inheritance. The example given in the german thread intrigues me though, it would mean that you can change the structure and buildup of previous class templates by adding a new one. I would consider that a design flaw in c++. Also, removing that option the hard way (just don't let them override them) would fix the inheritance problem, imo making for a clearer interface.
I hope that translation helped you
It didn't help me but I can speak enough german to follow the thread
. You guys live just around the corner from here.
Re:C++ use of specialization and inheritance
Posted: Tue Sep 12, 2006 1:01 pm
by Candy
Ok, it is a problem in gcc. Contrary to what that thread implied, you cannot specialize a class after instantiating it and expect the latter specialization to be used. It's mentioned explicitly as such in Stroustrup's book on C++, which should be pretty authoritative.
I'm going to take this on the gcc mailing list for now.
Re:C++ use of specialization and inheritance
Posted: Tue Sep 12, 2006 2:15 pm
by Candy
Ok, oops on that. They ripped it out in GCC 3.4 because the standard says you have to do it this way.