Default template argument in a function: reasonable but disallowed

Discussion in 'C++' started by chrisstankevitz@yahoo.com, Nov 9, 2006.

  1. Guest

    Apparently default template arguments can only be used in classes. I
    include two apps below. One works but is IMO messy. The other does
    not work and is IMO clean.

    Q1: Why would c++ dissallow the clean version?
    Q2: Is there a way to do what I want to do "cleanly" (as I define it :)

    The templated function writes a long to a binary stream in 64 bits.
    This code works for 32 and 64 bit long.

    Thanks!

    Chris

    //===== This code is messy, allows for user error, but compiles =====

    #include <fstream>

    template<typename Type, int NumBits>
    void BinaryWrite64Bit(Type Value, std::eek:stream& Stream);

    template<>
    void BinaryWrite64Bit<long, 32>(long Value, std::eek:stream& Stream)
    {
    static const long Zero = 0;
    Stream.write(reinterpret_cast<const char*>(&Zero), sizeof(Zero));
    Stream.write(reinterpret_cast<const char*>(&Value), sizeof(Value));
    }

    template<>
    void BinaryWrite64Bit<long, 64>(long Value, std::eek:stream& Stream)
    {
    Stream.write(reinterpret_cast<const char*>(&Value), sizeof(Value));
    }

    int main()
    {
    std::eek:fstream Stream;

    long Value = 10;

    BinaryWrite64Bit<long, sizeof(long)*8>(Value, Stream);

    return 0;
    }

    //===== This code is clean, robust but doesn't compile =====
    #include <fstream>

    template<typename Type, int NumBits = sizeof(Type)*8>
    void BinaryWrite64Bit(Type Value, std::eek:stream& Stream);

    template<>
    void BinaryWrite64Bit<long, 32>(long Value, std::eek:stream& Stream)
    {
    static const long Zero = 0;
    Stream.write(reinterpret_cast<const char*>(&Zero), sizeof(Zero));
    Stream.write(reinterpret_cast<const char*>(&Value), sizeof(Value));
    }

    template<>
    void BinaryWrite64Bit<long, 64>(long Value, std::eek:stream& Stream)
    {
    Stream.write(reinterpret_cast<const char*>(&Value), sizeof(Value));
    }

    int main()
    {
    std::eek:fstream Stream;

    long Value = 10;

    BinaryWrite64Bit(Value, Stream);

    return 0;
    }
     
    , Nov 9, 2006
    #1
    1. Advertising

  2. mlimber Guest

    wrote:
    > Apparently default template arguments can only be used in classes. I
    > include two apps below. One works but is IMO messy. The other does
    > not work and is IMO clean.
    >
    > Q1: Why would c++ dissallow the clean version?
    > Q2: Is there a way to do what I want to do "cleanly" (as I define it :)
    >
    > The templated function writes a long to a binary stream in 64 bits.
    > This code works for 32 and 64 bit long.
    >
    > Thanks!
    >
    > Chris
    >
    > //===== This code is messy, allows for user error, but compiles =====
    >
    > #include <fstream>
    >
    > template<typename Type, int NumBits>
    > void BinaryWrite64Bit(Type Value, std::eek:stream& Stream);
    >
    > template<>
    > void BinaryWrite64Bit<long, 32>(long Value, std::eek:stream& Stream)
    > {
    > static const long Zero = 0;
    > Stream.write(reinterpret_cast<const char*>(&Zero), sizeof(Zero));
    > Stream.write(reinterpret_cast<const char*>(&Value), sizeof(Value));
    > }
    >
    > template<>
    > void BinaryWrite64Bit<long, 64>(long Value, std::eek:stream& Stream)
    > {
    > Stream.write(reinterpret_cast<const char*>(&Value), sizeof(Value));
    > }
    >
    > int main()
    > {
    > std::eek:fstream Stream;
    >
    > long Value = 10;
    >
    > BinaryWrite64Bit<long, sizeof(long)*8>(Value, Stream);
    >
    > return 0;
    > }
    >
    > //===== This code is clean, robust but doesn't compile =====
    > #include <fstream>
    >
    > template<typename Type, int NumBits = sizeof(Type)*8>
    > void BinaryWrite64Bit(Type Value, std::eek:stream& Stream);
    >
    > template<>
    > void BinaryWrite64Bit<long, 32>(long Value, std::eek:stream& Stream)
    > {
    > static const long Zero = 0;
    > Stream.write(reinterpret_cast<const char*>(&Zero), sizeof(Zero));
    > Stream.write(reinterpret_cast<const char*>(&Value), sizeof(Value));
    > }
    >
    > template<>
    > void BinaryWrite64Bit<long, 64>(long Value, std::eek:stream& Stream)
    > {
    > Stream.write(reinterpret_cast<const char*>(&Value), sizeof(Value));
    > }
    >
    > int main()
    > {
    > std::eek:fstream Stream;
    >
    > long Value = 10;
    >
    > BinaryWrite64Bit(Value, Stream);
    >
    > return 0;
    > }


    How about using a dispatcher to automatically select an implementation:

    template<typename Type, int NumBits>
    void BinaryWrite64BitImpl(Type, std::eek:stream&);

    template<>
    void BinaryWrite64BitImpl<long, 32>(
    const long value,
    std::eek:stream& stream)
    {
    // ...
    }

    template<>
    void BinaryWrite64BitImpl<long, 64>(
    const long value,
    std::eek:stream& stream)
    {
    // ...
    }

    template<typename Type>
    void BinaryWrite64Bit(
    const Type value,
    std::eek:stream& stream)
    {
    BinaryWrite64BitImpl
    <
    Type,
    sizeof(Type)*CHAR_BIT
    >( value, stream );

    }

    int main()
    {
    std::eek:fstream Stream;
    const long Value = 10;
    BinaryWrite64Bit(Value, Stream);
    return 0;
    }

    Cheers! --M
     
    mlimber, Nov 9, 2006
    #2
    1. Advertising

  3. Guest

    mlimber wrote:
    > How about using a dispatcher to automatically select an implementation:


    Wow, that is cool, never saw that before. Thanks mlimber!

    I'm off to see where CHAR_BIT is defined (never saw that either)...

    Chris
     
    , Nov 9, 2006
    #3
  4. Salt_Peter Guest

    wrote:
    > mlimber wrote:
    > > How about using a dispatcher to automatically select an implementation:

    >
    > Wow, that is cool, never saw that before. Thanks mlimber!
    >
    > I'm off to see where CHAR_BIT is defined (never saw that either)...
    >
    > Chris


    Yep, cool.
    You'll find it in climits typically, although you might need to dig
    down to limits.h

    /* # of bits in a char */
    # define CHAR_BIT 8
     
    Salt_Peter, Nov 9, 2006
    #4
  5. Greg Guest

    wrote:
    > Apparently default template arguments can only be used in classes. I
    > include two apps below. One works but is IMO messy. The other does
    > not work and is IMO clean.
    >
    > Q1: Why would c++ dissallow the clean version?


    Apparently there is no good reason.

    > Q2: Is there a way to do what I want to do "cleanly" (as I define it :)


    Yes - compile your program with a C++0x compiler (may require a trip to
    the future). The next major version of C++ does allow function
    templates to specify default template type parameters.

    Greg
     
    Greg, Nov 9, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hunsal

    Disallowed Parent Path error

    Hunsal, May 20, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    596
  2. Replies:
    9
    Views:
    541
  3. Jim West
    Replies:
    3
    Views:
    775
    Jim West
    Oct 7, 2004
  4. nw
    Replies:
    0
    Views:
    332
  5. sandeep

    Undefined but reasonable

    sandeep, Sep 29, 2010, in forum: C Programming
    Replies:
    12
    Views:
    463
Loading...

Share This Page