Thread: Overloading Issue

  1. #1
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895

    Overloading Issue

    Hi,

    I've got a weird little problem. I've got a class that requires a pointer to a memory buffer, along with its size, at construction.
    Code:
    template<typename E>
    class buffer
    {
      E *m_ptr;
      std::size_t m_size;
    
    public:
      buffer(E *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
    For convenience and a bit of safety, I also offer this constructor:
    Code:
      template<int N>
      buffer(E (&ar)[N]) : m_ptr(ar), m_size(N) {}
    This way, you can construct it like this and it will infer the correct size:
    Code:
    char ar[5] = { 1, 2, 3, 4, 5 };
    buffer<char> b(ar);
    This works very nicely.

    Now, I also want to provide a constructor that takes an array reference AND a size, and uses the supplied size only if it doesn't exceed the array size:
    Code:
      template<int N>
      buffer(E (&ar)[N], std::size_t size) : m_ptr(ar), m_size(size < N ? size : N) {}
    }
    However, when I want to prove this works:
    Code:
    char ar[5] = { 1, 2, 3, 4, 5 };
    buffer<char> b(ar, 7);
    ... it actually chooses the pointer constructor.
    Thinking about it, it makes sense: the non-template is generally ordered before templates in overload resolution. However, I don't want it there.

    So, does anyone have any idea how I could get the array+size constructor to be used in this situation without destroying the other use cases?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Without doing any leg-work do you think boost::is_array<> could be utilized in some fashion?

    gg

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Hmm, perhaps something like this?
    Code:
    #include <iostream>
    #include <cstddef>
    
    template <typename E>
    class buffer {
      E *m_ptr;
      std::size_t m_size;
    public:
      template <typename T>
      buffer ( T ptr, std::size_t size )
        : m_ptr ( ptr ), m_size ( size )
      {
        std::cout<<"Pointer constructor\n";
      }
    
      template <int N>
      buffer ( E (&ar)[N], std::size_t size )
        : m_ptr ( ar ), m_size ( size < N ? size : N )
      {
        std::cout<<"Array constructor w/size\n";
      }
    
      template <int N>
      buffer ( E (&ar)[N] )
        : m_ptr ( ar ), m_size ( N )
      {
        std::cout<<"Array constructor\n";
      }
    };
    
    int main()
    {
      char ar1[5] = { 1, 2, 3, 4, 5 };
      buffer<char> b1(ar1);
    
      char ar2[5] = { 1, 2, 3, 4, 5 };
      buffer<char> b2(ar2, 7);
    
      char *p = new char[10];
      buffer<char> b3(p, 10);
    }
    Making the constructor a template function alters the overload order, and because the constructor is assigning a pointer to a pointer, a mismatched type for the first argument will result in a compile-time error because it's assigning X type to a pointer to E without a cast.
    My best code is written with the delete key.

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Good idea, Prelude. I had thought about making the pointer constructor a template, but somehow suffered from mental block and couldn't find this simple way.

    Codeplug, enable_if would indeed be another option.

    Thanks, I'll try these out.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Hmm, perhaps something like this?

    ingenious. =)

    >> E (&ar)[N]

    just curious...but what is the benefit of passing a reference to an array?
    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
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You cannot pass the array directly, as it would decay to a pointer in the parameter list. Only by passing it by reference can you preserve the array and, more importantly, enforce extent checking.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    you're right. I tried to instantiate the following function, but got an error unless I specified the template argument explicitly:

    Code:
    template <unsigned Size>
    void
    foo(int array[Size])
    {
     
    }
    //...
    foo(array); // error
    foo<1024>(array); // fine
    thanks.
    Last edited by Sebastiani; 09-22-2007 at 02:55 PM.
    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
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Prelude, your suggestion worked. Thanks a lot.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. unary operator overloading and classes
    By coletek in forum C++ Programming
    Replies: 9
    Last Post: 01-10-2009, 02:14 AM
  2. float calculation issue
    By George2 in forum C# Programming
    Replies: 1
    Last Post: 05-26-2008, 04:56 AM
  3. type safe issue
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 02-12-2008, 09:32 PM
  4. Simple operator overloading issue
    By Desolation in forum C++ Programming
    Replies: 1
    Last Post: 05-09-2007, 08:56 PM
  5. Overloading << Issue
    By dld333 in forum C++ Programming
    Replies: 1
    Last Post: 10-27-2005, 02:18 AM