Sign in to follow this  

Fun with templates

This topic is 4543 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone, I am a bit stumped with the errors I get from the compiler VC++ 8.0. Anyone can point out my errors? I am basically trying to have a templated object as a return type, and that is causing me problems. Note: this is just an example code, not an actual one. TIA, Peter ================================================================== template<typename T> class EntityItems { public: T items[]; }; template<int, typename T> class MonsterEntity { public: T items; int _count; }; template<typename T> class MonsterEntityManager { public: MonsterEntity<int, EntityItems<T> &> Exists(int itemKey); }; Compiler error: Error 4 error C2975: 'Core::MonsterEntity' : invalid template argument for 'unnamed-parameter', expected compile-time constant expression ==================================================================

Share this post


Link to post
Share on other sites
Dragongame, thanks for the reply.

I think that my example was oversimplified. I tried to create a small example, taking out the complexities of my own design.

In any case, here is my real classes, and the error:
======================================================================

template<typename TObject>
struct QueueMessage
{
const Message<TObject>& Msg; // The message to queue.
const MessageHandlerList<TObject>& HandlerList; // The looked-up HandlerList.

/// Cctor
QueueMessage(const Message<TObject>& msg, MessageHandlerList<TObject>& hndlrList) : Msg(msg), HandlerList(hndlrList){};

/// Destructor
~QueueMessage()
{
delete Msg;
};

};


template<typename TObject>
class MessageManager
{
private:
MessageManager();

protected:
const Core::Entity& _owner;
stdext::hash_map<Uint, MessageEntry<TObject>* > _msgRegistry;
std::multimap<Uint, QueueMessage<TObject>* > _queue;

public:
MessageManager(const Core::Entity<TObject>& owner);
~MessageManager();
std::multimap<Uint, QueueMessage<TObject>* >::iterator isQueued(Uint msgId);
};

The last line fails to compile (no definition for it in .cpp yet) with the following errors:

error C2146: syntax error : missing ';' before identifier 'isQueued'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int


So obviously, it doesn't understand the return type. I know the problem is the nested template, the QueueMessage<TObject>, because if I replace that one with any class that doesn't need a template or a basic data type, it compiles.

Furthermore, I have created an iterator the same exact way, to the letter, in other member function definitions of the same class (in the body of the member function) and it worked. It's only when I use it as a return type that I have a problem.

Any ideas guys?

Thank you very much!

Peter


Share this post


Link to post
Share on other sites
Sicrane, thanks a bunch!

I've been hitting my head into the wall for quite a while now, being new to templates and all. I have seen in my books that you're supposed to use typename when the compiler cannot resolve what exactly the template instantiation represents, as in:


template<class Parm, class U>
Parm minus(Parm* array, U value)
{
Parm::name * p; // Is this a pointer declaration or a multiplication?
// It is actually a multiplication.
}


template<class Parm, class U>
Parm minus(Parm* array, U value)
{
typename Parm::name * p; // Ok now, pointer declaration.
}


However I don't see exactly what got the compiler confused with the
std::multimap<Uint, QueueMessage<TObject>* >::iterator isQueued(Uint msgId);
line?

Would you, or someone else explain? And how come I only need to precise with typename for the return type, but not when declaring an iterator the same exact way in a body of a member function?

example:

std::multimap<Uint, QueueMessage<TObject>* >::iterator iter = this->_queue.find(msgId); // This works

Thanks!

Share this post


Link to post
Share on other sites
Quote:
Original post by nikdo
However I don't see exactly what got the compiler confused with the
std::multimap<Uint, QueueMessage<TObject>* >::iterator isQueued(Uint msgId);
line?

std::multimap<Uint, QueueMessage<TObject>* >::iterator iter = this->_queue.find(msgId); // This works

Thanks!


what happens when you remove the second Uint, like so:
std::multimap<Uint, QueueMessage<TObject>* >::iterator isQueued(msgId);

Share this post


Link to post
Share on other sites
DragonGame,

std::multimap<Uint, QueueMessage<TObject>* >::iterator isQueued(msgId);

simply won't compile, since msgId is not a type defined anywhere, but rather a parameter name. The compiler doesn't know what to do with that. As a matter of fact parameter names are totally optional in function / method declarations.
As a matter of fact most people don't write parameter names in the declarations; I do because I find it more descriptive.

Hence the following can be written:

std::multimap<Uint, QueueMessage<TObject>* >::iterator isQueued(Uint);

In any case, I don't know if you noticed or not, but Sicrane's solution of putting "typename" in front of the line worked. I am just wondering why the typename was required.

Peter

Share this post


Link to post
Share on other sites
You need to use typename whenever you use :: to get at a type depedent on a template parameter. In this example TObject is your template parameter, so
QueueMessage<TObject> is a type depedent on a template parameter. And since std::multimap<Uint, QueueMessage<TObject> *> depends on the type QueueMessage<TObject> then std::multimap<Uint, QueueMessage<TObject> *> is dependent on a template type paramter. And then you use :: to get at std::multimap<Uint, QueueMessage<TObject> *>'s iterator, you need to use typename in front of std::multimap<Uint, QueueMessage<TObject> *> in order for the :: to find iterator as a type.

Share this post


Link to post
Share on other sites
SiCrane,

thank you sincerely for taking the time today to respond to my questions. I understand now completely and appreciate your help.

I'm about to delve into "Modern C++ Design" by Andrei Alexandrescu, a fantastic book all about templates (and much more of course). Wish me luck!

Peter

Share this post


Link to post
Share on other sites

This topic is 4543 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this