locked
C++/CX generic <class T> delegate

    Question

  • Hi,

    Please help C# developers to pitch in to C++/CX.

    According to MSDN

    http://msdn.microsoft.com/en-us/library/windows/apps/hh755798.aspx

    Generic delegates          

    The declaration of a public generic delegate is emitted into metadata, and can then be specialized and instantiated by consuming code. This example declares a generic delegate:

    generic <typename T>
    delegate void  MyEventHandler(T p1, T p2);
    

    And that is it, about Generic delegates, period!!! Where is the code snippet?

    I am stuck with compilation error:

    Generator<StartEventArgs^>^ generator = () -> StartEventArgs^ { return ref new StartEventArgs(); };

    #include <iostream>
    using namespace std;
    
    using namespace Platform;
    using namespace Windows::Foundation;
    
    generic <class T> delegate void  Generator();
    
    ref class StartEventArgs sealed
    {
    
    };
    
    ref class BuyNow sealed
    {
    	internal:
    	event EventHandler<StartEventArgs^>^ Start;
    	void OnStart();	 
    };
    
    void BuyNow::OnStart()
    {
    	auto func = [] () -> StartEventArgs^ { return ref new StartEventArgs(); };
    	//Generator<StartEventArgs^>^ generator = () -> StartEventArgs^ { return ref new StartEventArgs(); };
    	Platform::Details::Console::WriteLine("Not Fine!");
    }
    
    int main(Platform::Array<Platform::String^>^ args)
    {	
    	BuyNow^ bn = ref new BuyNow();
    	bn->OnStart();	
    	std::cin.get(); 
    	return 0;
    }
    

    Here's the corresponding C# Code Snippet that works fine:

    using System;
    
    public sealed class StartEventArgs
    {
    
    }
    
    class BuyNow
    {
        public event EventHandler<StartEventArgs> Start;
    
        private delegate T Generator<T>();
    
        public void OnStart()
        {
            Generator<StartEventArgs> generator = () => { return new StartEventArgs(); };
            //Generator<StartEventArgs> generator = delegate { return new StartEventArgs(); };
            Console.WriteLine("Fine!");
        }    
    }
    
    class Program
    {
        public static void Main()
        {
            BuyNow bn = new BuyNow();
            bn.OnStart();
            Console.ReadKey();
        }
    }
    

    Please help.

    Thanks

    Friday, May 24, 2013 10:58 AM

Answers

  • Try using this:

    generic <class T>
    delegate T Generator();

    and this:

    	auto generator = ref new Generator<StartEventArgs^>( [] ()
        {
            return ref new StartEventArgs();
        });

    • Marked as answer by recherche Sunday, May 26, 2013 4:44 AM
    • Unmarked as answer by recherche Sunday, May 26, 2013 4:44 AM
    • Proposed as answer by Jesse Jiang Monday, May 27, 2013 2:21 AM
    • Marked as answer by recherche Monday, May 27, 2013 5:59 AM
    Friday, May 24, 2013 1:41 PM

All replies

  • Try using this:

    generic <class T>
    delegate T Generator();

    and this:

    	auto generator = ref new Generator<StartEventArgs^>( [] ()
        {
            return ref new StartEventArgs();
        });

    • Marked as answer by recherche Sunday, May 26, 2013 4:44 AM
    • Unmarked as answer by recherche Sunday, May 26, 2013 4:44 AM
    • Proposed as answer by Jesse Jiang Monday, May 27, 2013 2:21 AM
    • Marked as answer by recherche Monday, May 27, 2013 5:59 AM
    Friday, May 24, 2013 1:41 PM
  • Try using this:

    generic <class T>
    delegate T Generator();

    and this:

    	auto generator = ref new Generator<StartEventArgs^>( [] ()
        {
            return ref new StartEventArgs();
        });

    Thanks for the answer, jrboddie.


    • Edited by recherche Monday, May 27, 2013 6:41 AM typo
    Sunday, May 26, 2013 4:47 AM
  • Are you developing a Windows Store app?  Your use of main(), Console and std::cin, look strange to me in that context.

    Start from a template for Windows Store apps.

    Sunday, May 26, 2013 10:50 AM
  • Are you developing a Windows Store app?  Your use of main(), Console and std::cin, look strange to me in that context.

    Start from a template for Windows Store apps.

    Thanks for the reply, jrboddie. That was just for code snippet using CxxWinRTTemplate for illustrating. Actually I am a .NET developer pitching into C++/CX (and learning). Since, MSDN does not have elaborate syntax or code snippets for generic delegates (http://msdn.microsoft.com/en-us/library/windows/apps/hh755798.aspx), I use CxxWinRTTemplate (http://visualstudiogallery.msdn.microsoft.com/8116acc4-747b-4330-bfd1-fce04d798f4a) to understand C++/CX  syntax using a console application.

    You code snippet works fine. Mea culpa.


    • Edited by recherche Monday, May 27, 2013 6:41 AM typo
    Monday, May 27, 2013 5:47 AM
  • Try using this:

    generic <class T>
    delegate T Generator();

    and this:

    	auto generator = ref new Generator<StartEventArgs^>( [] ()
        {
            return ref new StartEventArgs();
        });

    What about classes with constructor overload?

    For example:

    Generator<AuthEventArgs^>^ generator =
     ref new Generator<AuthEventArgs^>
     (
     [&] ()
      {
                 
        ref new AuthEventArgs(token);
      }
     );
    }

    I got this error:

    Warning 1 warning C4570: 'Generator' : is not explicitly declared as abstract but has abstract functions C:\Users\rsomaskandan\Documents\Visual Studio 2012\Projects\CxxWinRTTemplate1\CxxWinRTTemplate1\RefTemplate.cpp 10 1 CxxWinRTTemplate1
    Error 2 error C2440: 'return' : cannot convert from 'void' to 'AuthEventArgs ^' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\vccorlib.h 850 1 CxxWinRTTemplate1

    Here's the complete code snippet for you:

    // RefTemplate.cpp : Defines the entry point for the console application.
    //
    
    #include <iostream>
    using namespace std;
    using namespace Platform;
    using namespace Windows::Foundation;
    
    generic <class T>
    delegate T Generator();
    
    		enum class ErrorType
    		{
    			UNKNOWN = 0,
    			HTTP = 1,
    			API = 2,
    			NETWORK = 3
    		};
    
    		ref class StartEventArgs sealed
    		{
    
    		};
    
    		ref class AuthEventArgs sealed
    		{		
    			private:
    				String^ authEventArgsToken;
    
    			public:
    				AuthEventArgs(String^ token)
    				{
    					Token = token;
    				}
    				property String^ Token
    				{
    					String^ get()
    					{
    						return authEventArgsToken;
    					}
    					void set(String^ value)
    					{
    						authEventArgsToken = value;
    					}
    				}
    		};
    
    		ref class CancelEventArgs sealed
    		{		
    			private:
    				String^ cancelEventArgsToken;
    
    			public:
    				CancelEventArgs(String^ token)
    				{
    					Token = token;
    				}
    				property String^ Token
    				{
    					String^ get()
    					{
    						return cancelEventArgsToken;
    					}
    					void set(String^ value)
    					{
    						cancelEventArgsToken = value;
    					}
    				}
    		};
    
    		ref class ErrorEventArgs sealed
    		{		
    			private:
    				ErrorType errorEventArgsType;
    				String^ errorEventArgsCode;
    				String^ errorEventArgsMessage;
    				String^ errorEventArgsDetail;
    
    			public:
    				ErrorEventArgs(String^ name, String^ message, String^ detail)
    				{					
    					 Code = name;
    					 Message = message;
    					 Detail = detail;
    				}
    
    				property String^ Code
    				{
    					String^ get()
    					{
    						return errorEventArgsCode;
    					}
    					void set(String^ value)
    					{
    						errorEventArgsCode = value;
    					}
    				}
    
    				property String^ Message
    				{
    					String^ get()
    					{
    						return errorEventArgsMessage;
    					}
    					void set(String^ value)
    					{
    						errorEventArgsMessage = value;
    					}
    				}
    
    				property String^ Detail
    				{
    					String^ get()
    					{
    						return errorEventArgsDetail;
    					}
    					void set(String^ value)
    					{
    						errorEventArgsDetail = value;
    					}
    				}
    		};
    
    		ref class CompleteEventArgs sealed
    		{		
    			private:
    				String^ errorEventArgsToken;
    				String^ errorEventArgsTransactionID;
    				String^ errorEventArgsPayerID;
    
    			public:
    				CompleteEventArgs(String^ token, String^ transactionID, String^ payerID)
    				{
    					 Token = token;
    					 TransactionID = transactionID;
    					 PayerID = payerID;
    				}
    				property String^ Token
    				{
    					String^ get()
    					{
    						return errorEventArgsToken;
    					}
    					void set(String^ value)
    					{
    						errorEventArgsToken = value;
    					}
    				}
    
    				property String^ TransactionID
    				{
    					String^ get()
    					{
    						return errorEventArgsTransactionID;
    					}
    					void set(String^ value)
    					{
    						errorEventArgsTransactionID = value;
    					}
    				}
    
    				property String^ PayerID
    				{
    					String^ get()
    					{
    						return errorEventArgsPayerID;
    					}
    					void set(String^ value)
    					{
    						errorEventArgsPayerID = value;
    					}
    				}				
    		};
    
    ref class BuyNow sealed
    {
    	internal:
    	event EventHandler<StartEventArgs^>^ Start;
    	void OnStart();	 
    	void OnAuth(String^ token);
    	void OnCancel(String^ token);
    	void OnError(String^ name, String^message);
    	void OnError(String^ name, String^ message, String^ detail);
    	void OnComplete(String^ token, String^ transactionId, String^payerId);
    };
    
    void BuyNow::OnStart()
    {
    	Generator<StartEventArgs^>^ generator = ref new Generator<StartEventArgs^>( [] ()
        {
            return ref new StartEventArgs();
        });
    }
    
    void BuyNow::OnAuth(String^ token)
    {
    Generator<AuthEventArgs^>^ generator = 
    	ref new Generator<AuthEventArgs^>
    	(
    	[&] ()
    		{
    													
    				ref new AuthEventArgs(token);
    		}
    	);
    }
    
    void BuyNow::OnCancel(String^ token)
    {
    	Generator<CancelEventArgs^>^ generator = ref new Generator<CancelEventArgs^>
    											(
    											[&] ()
    												{
    													
    													 ref new CancelEventArgs(token);
    												}
    											);
    }
    
    void BuyNow::OnError(String^ name, String^message)
    {					
    	OnError(name, message, nullptr);
    }
    
    void BuyNow::OnError(String^ name, String^ message, String^ detail)
    {
    	Generator<ErrorEventArgs^>^ generator = ref new Generator<ErrorEventArgs^>
    											(
    											[&] ()
    												{
    													
    													  ref new ErrorEventArgs(name, message, detail);
    												}
    											);		
    	//Emit<ErrorEventArgs>(generator);
    }
    
    void BuyNow::OnComplete(String^ token, String^ transactionId, String^payerId)
    {
    	Generator<CompleteEventArgs^>^ generator = ref new Generator<CompleteEventArgs^>
    											(
    											[&] ()
    												{
    													
    													 ref new CompleteEventArgs(token, transactionId, payerId);
    												}
    											);
    
    	//EmitAndComplete<CompleteEventArgs>(generator);
    }
    
    
    int main(Platform::Array<Platform::String^>^ args)
    {	
    	BuyNow^ bn = ref new BuyNow();
    	bn->OnStart();	
    	std::cin.get(); 
    	return 0;
    }
    

    I am a .NET developer pitching into C++/CX (and learning). Please help with Lamda expression syntax/code snippet illustration in C++/CX as MSDN documentation didn't help.

    Thanks


    • Edited by recherche Monday, May 27, 2013 6:44 AM typo
    Monday, May 27, 2013 6:40 AM