C++ Functor template problem

Started by
12 comments, last by assainator 13 years, 3 months ago
Hello all,

I'm facing a problem with Functors. I have made the following functor class
template <typename classT, typename retT, typename P1>class Functor1{	public:		Functor1(classT *state, retT (classT::*func)(P1)) : _func(func), _state(state){}		Functor1() : _state(NULL), _func(NULL){}		retT operator()(P1 arg)		{			if(_func != NULL && _state != NULL)				return (*_state.*_func)(arg);			else				return -1;		}		retT Call(P1 arg)		{			if(_func != NULL && _state != NULL)				return (*_state.*_func)(arg);			else				return -1;		}	private:		classT *_state;		retT (classT::*_func)(P1);};


I have the button class:
namespace Alluminium{	class AlButton : public AlWidget	{		public:			AL_API AlButton(AlWidget *Parent, Point2<int> Size, Point2<int> Position, std::wstring text);			AL_API virtual ~AlButton(void);			AL_API virtual LRESULT OnLeftClick(Point2<int> MousePosition);			template <typename T>			Functor1<T, LRESULT, Point2<int>> OnLeftClickCallback;					virtual LRESULT HandleEvent(unsigned int msg, WPARAM wParam, LPARAM lParam);	};}


And the functor is called like:
LRESULT AlButton::OnLeftClick(Point2<int> MousePosition){	return OnLeftClickCallback.Call(MousePosition);}


But I get the below compiler error and then I get a message that the "Microsoft(R) Optimized C\C++ Compiler" crashed

Quote:
1>albutton.hpp(20): fatal error C1001: An internal error has occurred in the compiler.
1> (compiler file 'msc1.cpp', line 1420)
1> To work around this problem, try simplifying or changing the program near the locations listed above.
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information


Can anybody tell me why the compiler crashes and how I should fix this?

Thanks in advance,
assainator
"What? It disintegrated. By definition, it cannot be fixed." - Gru - Dispicable me

"Dude, the world is only limited by your imagination" - Me

Advertisement
When you call a pointer-to-method, don't you have to use the following syntax:

state->*func(arg)

?

Otherwise, you should get a compiler error, I believe.
Well, it doesn't make a difference if I use your syntax.

assainator
"What? It disintegrated. By definition, it cannot be fixed." - Gru - Dispicable me

"Dude, the world is only limited by your imagination" - Me

Which version of the compiler are you using? If this is Visual C++ 2010, send MS a bug report.

Also, this code makes no sense:
template <typename T>Functor1<T, LRESULT, Point2<int>> OnLeftClickCallback;

By fixing it you might be able to work around the ICE.
Any Idea what I should/could use instead?

assainator
"What? It disintegrated. By definition, it cannot be fixed." - Gru - Dispicable me

"Dude, the world is only limited by your imagination" - Me

Quote:Original post by assainator
Any Idea what I should/could use instead?

assainator


What is it supposed to do? You want to turn that 'T' in to something definite.
Well,

The idea is that if I create a class, that I can pass a function (and a state) and so providing a callback for an action by the button.
In the button class, the return type and argument type are known (LRESULT and Point2<int> respectively) but the state type isn't. It could be a Window, it could also be another button. And that is why I tried the first snippet. I have tried using the base class (AlWidget) as the replacement for T but as the function OnExit(see below snippet) is not a function of the AlWidget class, that won't work.

A example with a window as state
class MainWindow : public AlWindow{	public:		MainWindow()		{			//create button				     /* parent  Size                Position         text/title*/			btn = new Button(this, Point2<int>(75,25), Point2<int>(0,0), L"Exit");			//set callback			   /*statetype  ret type  arg type    state  func */			btn->OnLeftClickCallback = Functor1<MainWindow, LRESULT, Point2<int>>(this, &OnExit);		}	protected:		//The function that matches the prototype		LRESULT OnExit(Point2<int> MousePosition)		{			this->Close();		}		//The button			AlButton *btn;};



assainator
"What? It disintegrated. By definition, it cannot be fixed." - Gru - Dispicable me

"Dude, the world is only limited by your imagination" - Me

If operator() and Call do exactly the same thing, it would be better to reuse the code by having one call the other.

What is the template <typename T> for? Why not just use:

Functor1<LRESULT, Point2<int>> OnLeftClickCallback;

with no template?

You can't have template declarations of member variables like you have.
-----------------------http://poita.org - C++ and D programming articles.
Quote:Original post by Poita
If operator() and Call do exactly the same thing, it would be better to reuse the code by having one call the other.

What is the template <typename T> for? Why not just use:

Functor1<LRESULT, Point2<int>> OnLeftClickCallback;

with no template?

You can't have template declarations of member variables like you have.


But how do I save a pointer to the state of a object then? In my last post, in my example, you see that the Functor1 need's a state type and a state.

assainator
"What? It disintegrated. By definition, it cannot be fixed." - Gru - Dispicable me

"Dude, the world is only limited by your imagination" - Me

In that case, you need to make sure that AlButton is a template class (with typename T) instead of just that single member. Then, in MainWindow, just instantiate the AlButton with AlButton<MainWindow>
-----------------------http://poita.org - C++ and D programming articles.

This topic is closed to new replies.

Advertisement