* Marco Jez:
Is it legal, in a class template's member function, to instantiate the same
class template but with a different type as argument?
Yes.
The following code is
very simple and I'd expect it to compile, but it makes both MSVC and gcc
freeze and never return. Sometimes I get an "internal compiler error"
instead.
struct Instance_base
{
virtual ~Instance_base() {}
virtual Instance_base* mkptr() = 0;
};
template<typename T>
struct Instance: Instance_base
{
T _inst;
Instance(const T &v): _inst(v) {}
Instance_base* mkptr() { return new Instance<T*>(&_inst); }
};
Instance_base* inst = new Instance<int>(3);
The offending line is that of Instance::mkptr(), if I remove it (and I make
the base class' method non-abstract) everything compiles ifne. Any clues?
You have an infinitely recursive template, just the same as e.g.
template< typename T >
int foo(){ return foo<T*>(); }
Amazingly MSVC is able to issue an error for this definition in almost no
time, "... too complex", but it insists that that is an error in <ios>...
The interesting question, too me, is whether 'mkptr' should really be
recursively instantiated, because it's never actually used.
So although the immediate problem fix is very clear, namely don't recurse
infinitely, and probably you _meant_ to write something like
Instance_base* mkptr() { return new Instance(_inst); }
the question you ask is not as clear, and I don't know the answer; however I
expect that someone will provide the answer, because it's nothing complicated,
just a matter of knowing or using the time to find the technical rule.
Btw., it's not a good idea to use an underscore at the start of a name.
Names starting with underscore followed by uppercase are reserved for the
implementation, and in practice one should regard that rule as the more
general that names staring with underscore are reserved.
--
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?