Thread: problem instantiating template with pointers

  1. #1
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708

    Question problem instantiating template with pointers

    I can't figure out why this won't compile:

    Code:
    template <class T, T init = T()> class test { };
    
    int
    main(void)
    {
    	test<int, 1024> a; /* ok */
    	test<int> b; /* ok */
    	test<int*, 0> c; /* no */
    	test<int*> d; /* ok / no (depends on the compiler) */
    }
    any ideas?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  2. #2
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    MSVC 2003 doesn't seem to mind. Perhaps it doesn't like converting 0 to a pointer? Try NULL, or (int *)0.

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    I tried that too, but with mixed results...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    What's the error message? With Comeau online it is:
    Code:
    "ComeauTest.c", line 7: error: argument of type "int" is incompatible with template
              parameter of type "int *"
      	test<int*, 0> c; /* no */
    which would seem to indicate skorman00 is correct. The (int *)0 fixes it there.

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    o.k., thanks. but mingw still won't compile what you guys suggested nor the last two examples I posted - the complaint is: 'a casts to a type other than an integral or enumeration type cannot appear in a constant-expression'. not sure, but it may be something in the standard (which mingw sticks pretty close to). I wonder if there's a workaround for that?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I would imagine it would be a bug in the compiler. VC++ 2003 and Comeau are fairly standards compliant themselves, and since 0 is a valid pointer you should be able to use it there.

    So it doesn't compile d above? What is the error when you only try d?

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    it says: ' "0u" is not a valid template argument - it must be the address of an object with external linkage'.

    >> I would imagine it would be a bug in the compiler.

    it could very well be. but mingw is one of the strictest compilers out there - in fact, I've noticed that if something compiles with mingw, it will probably compile with any other compiler. not that it doesn't have it's share of bugs - it does (there have been a few internal compiler errors using templates I've come across), but all in all it seems to follow the standard to a 'T', making it a great tool for writing portable code. another thing I noticed with this particular project is mingw won't let you use operator delete on a void*. It seems to me that in both of these cases the compiler should have issued a warning instead of an error...odd.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I would search over in comp.lang.c++.moderated if you haven't already, and consider asking about this there if you don't find anything. Compiler writers themselves often answer there, so you are more likely to get a good explanation. I'm not sure I even want to try to figure out where to look in the standard for such an issue.

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    well said.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  10. #10
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    I don't know why I chose to wander into the standard for this other than just curiousity. A bit I happened upon (14.3.2p5):
    for a non-type template-parameter of type pointer to object, qualification conversions (4.4) and the array-to-pointer conversion (4.2) are applied. [Note: In particular, neither the null pointer conversion (4.10) nor the derived-to-base conversion (4.10) are applied. Although 0 is a valid template-argument for a non-type template-parameter of integral type, it is not a valid template-argument for a non-type template-parameter of pointer type. ]
    FWIW
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    ah, so basically, even though it compiles on some compilers, it shouldn't. but I'm confused about the default template parameter now...calling a constructor isn't exactly a constant expression - I wonder if that's invalid, too? anyway, thanks for looking that up, Dave.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  2. Specialising a member function with a template template parameter
    By the4thamigo_uk in forum C++ Programming
    Replies: 10
    Last Post: 10-12-2007, 04:37 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. very weird problem (pointers I think)
    By hannibar in forum C Programming
    Replies: 2
    Last Post: 10-11-2005, 06:45 AM
  5. problem , need pointers. thanks
    By mobius in forum C Programming
    Replies: 4
    Last Post: 09-03-2001, 05:12 AM