Tech Off Post

Single Post Permalink

View Thread: C++0x (vs2010) question, please tell me what i'm doing wrong
  • User profile image
    Burkholder

    @Mr Crash: For your specific problem, I like Dexter's way better; however, since stuff like this pops up occassionally, here is another way:

    #include <iostream>
    #include <memory>
    #include <functional>
    
    #include <windows.h>
    
    using namespace std;
    
    //=========================================================
    
    /*
    // Dexter's code:
    template<typename T>  
    class test_c { 
    public:  
        explicit test_c(T p, std::function<void(T)> func)  
            : m_p(p), m_Func(func) { 
        }      
          
        ~test_c(void) {         
            m_Func(m_p); 
        } 
          
        T get(void) const {         
            return m_p; 
        } 
      
    private:     
        T m_p; 
        const std::function<void(T)> m_Func; 
    };
    */
    
    // A dumbed-down version of the functors presented around
    // page 110 of Modern C++ Design by Andrei Alexandrescu:
    template < typename RESULT_TYPE, typename PARAMETER_TYPE >
    class functor_base_t {
        public:
            virtual ~functor_base_t () {
                //
            }
            virtual RESULT_TYPE operator () ( PARAMETER_TYPE ) = 0;
    };
    
    template < typename RESULT_TYPE, typename PARAMETER_TYPE, typename FUNCTOR >
    class functor_handler_t : public functor_base_t< RESULT_TYPE, PARAMETER_TYPE > {
        FUNCTOR m_functor;
        public:
            functor_handler_t ( FUNCTOR functor ) : m_functor( functor ) {
                //
            }
            virtual ~functor_handler_t () {
                //
            }
            virtual RESULT_TYPE operator () ( PARAMETER_TYPE parameter ) {
                return m_functor( parameter );
            }
    };
    
    template < typename TYPE >
    class test_c {
        private:
            typedef void RESULT_TYPE;
            typedef TYPE PARAMETER_TYPE;
    
            PARAMETER_TYPE m_parameter;
            std::shared_ptr< functor_base_t< RESULT_TYPE, PARAMETER_TYPE > > m_functor_handler;
        public:
            template < typename FUNCTOR >
            explicit test_c ( PARAMETER_TYPE parameter, FUNCTOR functor ) :
                m_parameter( parameter ),
                m_functor_handler(
                    new functor_handler_t<
                        RESULT_TYPE,
                        PARAMETER_TYPE,
                        FUNCTOR
                    >( functor )
                )
            {
                //
            }
            ~test_c () {
                ( *m_functor_handler )( m_parameter );
            }
            PARAMETER_TYPE const & get () const {
                return m_parameter;
            }
    };
    
    //=========================================================
    
    inline void normal_func ( int p ) {
        cout << "p: " << p << endl;
    }
    
    struct normal_struct_func {
        inline void operator() (int p) const {
            cout << "p: " << p << endl;
        }
    };
    
    template< typename T, typename Function >
    inline void test_f ( T p, Function func ) {
        func( p );
    }
    
    int main () {
        // test_f tests
        test_f( 11, [] ( int p ) { cout << "p: " << p << endl; } );
        test_f( 22, normal_func );
        test_f( 33, normal_struct_func() );
    
        // test_c tests
        test_c< int > tc1( 11, [] ( int p ) { cout << "p: " << p << endl; } );
        test_c< int > tc2( 22, normal_func );
        test_c< int > tc3( 33, normal_struct_func() );
    
        test_c< int * > tc4(
            new int,
            [] ( int * ptr ) {
                cout << "tc4: " << *ptr << endl;
                delete ptr;
            }
        );
        *tc4.get() = 44;
        test_c< int * > tc5(
            new int[ 3 ],
            [] ( int * arr ) {
                int const * i = &arr[ 0 ];
                int const * end = &arr[ 3 ];
                cout << "tc5: { ";
                if ( i != end ) {
                    cout << *i;
                    for ( ++i ; i != end; ++i )
                        cout << ", " << *i;
                }
                cout << " }" << endl;
                delete[] arr;
            }
        );
        tc5.get()[ 0 ] = 55;
        tc5.get()[ 1 ] = 56;
        tc5.get()[ 2 ] = 57;
    
    #define scoped test_c
    
        // 1:
        scoped<HMODULE> dll(LoadLibraryA("kernel32.dll"), [](HMODULE h){FreeLibrary(h);});
    
        // 2:
        scoped<int*> ptr2(new int, [](int *p){delete p;});
    
        // 3:
        scoped<int*> ptr3(new int[100], [](int *p){delete[] p;});
    
        // 4:
        scoped<int> ptr4(1974, [](int p){ cout << p << endl;});
    
        return 0;
    }
    
    This works in VC++2010 and MinGW's port of g++ 4.5.2.  Here's the command line for MinGW's g++ 4.5.2:
    g++ -o main.exe main.cpp -std=c++0x -march=native -O3 -Wall -Wextra -Werror
    This code produces the following output:
    p: 11
    p: 22
    p: 33
    1974
    tc5: { 55, 56, 57 }
    tc4: 44
    p: 33
    p: 22
    p: 11

    Hope This Also Helps,
    Joshua Burkholder