CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 19
  1. #1
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Compiler problem or feature?

    Ok, what I have tried to do here is probably one of those "reasonable-looking but faulty" uses of STL.

    Here is my "sample" code which illustrates the problem;


    template < typename T >
    class H
    {
    private:
    map< string, T > m_map;
    public:
    template< typename Predicate >
    RemoveCopyIf( H< T >& rhs, Predicate pr )
    {
    m_map.clear();
    remove_copy_if( rhs.m_map.begin(), rhs.m_map.end(),
    inserter( m_map, m_map.begin() ), pr );
    }
    void Insert( const string& s, const T& t )
    {
    m_map[s] = t;
    }
    };

    class J
    {
    private:
    int m_x;
    public:
    J( int x=0 ) : m_x( x )
    {
    }
    int x() const { return m_x; }

    // keep default copy constructor and operator=
    template < typename K >
    static bool IsOdd( const std:air< K, J > & kjPair )
    {
    return ( (kjPair.second.m_x & 1) != 0);
    }
    };

    template < typename K >
    bool IsOdd( const std:air< K, J > & kjPair )
    {
    return ( ( kjPair.second.x() & 1 ) != 0 );
    }


    int main()
    {
    H< J > h1;
    H< J > h2;

    h1.Insert( "one", J(1) );
    h1.Insert( "two", J(2) );
    h1.Insert( "three", J(3) );
    h1.Insert( "four", J(4) );

    h2.RemoveCopyIf( h1, J::IsOdd< string > ); // internal compiler error
    h2.RemoveCopyIf( h1, IsOdd< string > ); // link error if above line commented out
    return 0;
    }



    attempting to compile with VC6

    My guess is that the predicate must be a proper function pointer for the predicate and the compiler can't find one. (Is that the cause?)

    btw. in my real code I used the static member function with the key filled in (non-template) after the code above failed with the internal compiler error, and I also used Nicolai M. Josuttis's asso_inserter() implementation.

    I just posted this here because I'm curious (and it would have been nice to do what I was trying above)

    Add the below, for example, and the above works (whether as static in the class or in global space)


    bool IsOdd( const std:air< string, J > & kjPair )
    {
    return ( ( kjPair.second.x() & 1 ) != 0 );
    }





    The best things come to those who rate

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Compiler problem or feature?

    Here is the error when compiled with the on-line compiler at http://www.comeaucomputing.com


    Thank you for testing your code with Comeau C/C++!
    Your Comeau C/C++ test results are as follows:

    Comeau C/C++ 4.3 BETA#2 (Feb 17 2002 22:07:43)
    Copyright 1988-2002 Comeau Computing. All rights reserved.

    "12412.c", line 62: error: no instance of function template
    "H<T>::RemoveCopyIf [with T=J]" matches the argument list
    The argument types that you used are: (H<J>, <unknown-type&gt
    object type is: H<J>
    h2.RemoveCopyIf( h1, J::IsOdd< string > );
    ^

    1 error detected in the compilation of "12412.c".

    Tell others about http://www.comeaucomputing.com/tryitout !
    In strict mode, with -tused, Compile failed
    Hit the Back Button to review your code and compile options.
    Go Buy Comeau C/C++!! Check out the beta for new C compiler backends

    The error points to the same location as VC++. Try this on another compiler and see if it works.

    Regards,

    Paul McKenzie


  3. #3
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Compiler problem or feature?

    thanks for the info about the compiler but I still don't get it.

    How is template function J::IsOdd<string> any different from the standalone IsOdd with string hard-coded in?

    Same line as VC++ but that gave me an "internal compiler error" which means nothing.


    The best things come to those who rate

  4. #4

    Re: Compiler problem or feature?

    You should do like this

    typedef bool (*PF)( const pair< string , J >& );
    h2.RemoveCopyIf<PF>( h1, IsOdd<string> );
    h2.RemoveCopyIf<PF>( h1, J::IsOdd<string> );



  5. #5

    Re: Compiler problem or feature?

    The previous post cannot be compiled,
    I think it has to be the following.

    typedef bool (*PF)( const pair< string , J >& );
    PF p = IsOdd<string>;
    PF p1 = J::IsOdd;
    h2.RemoveCopyIf( h1, p );
    h2.RemoveCopyIf( h1, p1 );


  6. #6
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Compiler problem or feature?

    I got my code to compile by using string (hard coded into J::IsOdd - well the equivalent anyway)

    How do you make it work with a template function where string is a variable type?

    typedefs can make the code look neater but they don't add extra functionality.


    The best things come to those who rate

  7. #7

    Re: Compiler problem or feature?

    type PF has declared the key type of pair is string, so that the compiler can instantiate the template.

    typedef can tell the compiler the assured type .


  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Compiler problem or feature?

    The code now also compiles with the Comeau on-line compiler with the changes made. So there must be something in typedef-ing non-trivial types if you intend to make them template arguments. Two compilers (VC++ and Comeau) coming up with the same errors, and then get corrected with the same change -- doesn't seem to be a coincidence.

    BTW, the Comeau compiler adheres to the current standard much better than VC++, so there is no chance of some common compiler code being shared.

    Regards,

    Paul McKenzie


  9. #9
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Compiler problem or feature?

    which surprises me. I know sometimes typedef'ing fixes problems on VC++ but didn't expect it to be part of a "standard".

    I assume Tim Tsui meant that the typedefs should be made in the local function (main in the example), so that J can still have the static template member function with a general key type.


    The best things come to those who rate

  10. #10
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Compiler problem or feature?

    (it still failed with internal compiler error in VC++ though )




    The best things come to those who rate

  11. #11
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Compiler problem or feature?

    Hmm...I have Borland C++ Builder 5.0 at home. Maybe I'll try it there to see what it says. So far, only Comeau handles the typedef solution.

    Regards,

    Paul McKenzie




  12. #12

    Re: Compiler problem or feature?

    h2.RemoveCopyIf( h1, &IsOdd<string> );
    h2.RemoveCopyIf( h1, &J::IsOdd<string> );
    The above can be compiled under gcc.
    While under SGI CC , these must be
    typedef bool (*PF)( const pair< string , J >& );
    h2.RemoveCopyIf<PF>( h1, IsOdd<string> );
    h2.RemoveCopyIf<PF>( h1, J::IsOdd<string> );

    In VC6 , they have to be
    typedef bool (*PF)( const pair< string , J >& );
    PF p = IsOdd<string>;
    PF p1 = J::IsOdd;
    h2.RemoveCopyIf( h1, p );
    h2.RemoveCopyIf( h1, p1 );


    It seems a templat argument of a function must be deduced from a call in VC , while it can be given in SGI CC and gcc.


  13. #13
    Join Date
    Feb 2002
    Posts
    81

    Re: Compiler problem or feature?

    The internal compiler error occures very often, when there is some syntax error in template class definitions. Unfortunately, I cannot say what's wrong in this code without trying it.

    It is like the static method declaration is not what VC++ compiler likes. If you modify not to be template, it works:


    static bool IsOdd( const std:air< string, J > & kjPair )
    {
    return ( (kjPair.second.m_x & 1) != 0);
    }




    Your static method implementation may be considered as partial template specialization, which, unfortunately, is not supported by VC.


  14. #14
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    I solved my own problem

    by using a functor class instead of a static template member function. I did, however, have a problem trying to make the nested template class a friend (so it calls a public method)


    template < typename T >
    class H
    {
    private:
    map< string, T > m_map;
    public:
    template< typename Predicate >
    void RemoveCopyIf( H< T >& rhs, Predicate pr )
    {
    m_map.clear();
    remove_copy_if( rhs.m_map.begin(), rhs.m_map.end(),
    inserter( m_map, m_map.begin() ), pr );
    }
    void Insert( const string& s, const T& t )
    {
    m_map[s] = t;
    }
    };

    class J
    {
    private:
    int m_x;
    public:
    J( int x=0 ) : m_x( x )
    {
    }
    int x() const { return m_x; }

    // keep default copy constructor and operator=

    template < typename K >
    struct IsOdd
    {
    bool operator() ( const std:air< K, J > & kjPair )
    {
    return ( (kjPair.second.x() & 1) != 0);
    }
    };
    };

    int main()
    {
    H< J > h1;
    H< J > h2;

    h1.Insert( "one", J(1) );
    h1.Insert( "two", J(2) );
    h1.Insert( "three", J(3) );
    h1.Insert( "four", J(4) );

    h2.RemoveCopyIf( h1, J::IsOdd< string >() );
    return 0;
    }



    This compiles fine on Visual C++, althugh I haven't tried running it outputting
    the results (of h2)

    (Anyone resolve how I could make the inner template class a friend of J ? )


    The best things come to those who rate

  15. #15
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Compiler problem or feature?

    I got it to work in the end by using a nested template functor class instead of a function. I haven't yet worked out how to make this class a friend. I tried

    template < typename K > friend J::IsOdd< K >;



    but got a compiler error.


    The best things come to those who rate

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured