0

Here's the source code of std::default_delete from Visual Studio 2017 Community edition.

template<class _Ty>
struct default_delete<_Ty[]>
{
    // default deleter for unique_ptr to array of unknown size
    constexpr default_delete() _NOEXCEPT = default;

    template<class _Uty, class = typename enable_if<is_convertible<_Uty(*)[], _Ty(*)[]>::value, void>::type>
    default_delete(const default_delete<_Uty[]>&) _NOEXCEPT
    {
        // construct from another default_delete
    }

    template<class _Uty, class = typename enable_if<is_convertible<_Uty(*)[], _Ty(*)[]>::value, void>::type>
    void operator()(_Uty *_Ptr) const _NOEXCEPT
    {
        // delete a pointer
        static_assert(0 < sizeof (_Uty), "can't delete an incomplete type");
        delete[] _Ptr;
    }
};

I noticed the template parameters _Uty(*)[] and _Ty(*)[] in is_convertible<_Uty(*)[], _Ty(*)[]> inside array specialization.

If it was _Ty(&)[] then I would know for sure that it's a reference to array of type _Ty, as covered in this post, but have no clue whatsoever on what _Ty(*)[] means. It'll be really helpful if someone can shed light on this exotic template param.

EDIT: Many thanks to all of ya! I managed to rig up a function taking pointer to array.

template <typename T>
T* func0(T(*parr)[], std::initializer_list<T> args)
{
    int i = 0;
    for (T arg : args)
        (*parr)[i++] = arg;
    return *parr;
}

template <typename T, unsigned S>
T* func1(T(*parr)[S], std::initializer_list<T> args)
{
    int i = 0;
    for (T arg : args)
        (*parr)[i++] = arg;
    return *parr;
}

int main(void)
{
    std::string strs[5];
    //std::string* pstrs = func1(&strs, {"133", "233", "333", "433", "533"}); // Not working! Cannot deduce template param T from args
    std::string* pstrs = func1<std::string, 5>(&strs, {"133", "233", "333", "433", "533"}); // Works fine!
    //std::string* pstrs = func0<std::string, 5>(&strs, {"133", "233", "333", "433", "533"}); // Not working! No instance of function template match
    return 0;
}

I wonder why template param T cannot be deduced from args passed to func1 ? Also, it seems that the size information S in T(*parr)[S] is a must.

David Lee
  • 859
  • 1
  • 11
  • 13
  • 1
    Pointer to an array of type `_Ty`, of course. E.g. this is what you'd get if you apply address-of `&` operator to a reference to an array of type `_Ty` (whose existence you already know about). – Igor Tandetnik Jun 25 '17 at 13:57
  • 1
    `T(*)[]` is just a pointer to an array of an unspecified number of `T` objects. The confusing bit is testing its convertability as pointers (or references) to arrays of one type do not convert to pointers (or references) of other arrays. I *guess* non-`const` to `const` conversion is still allowed. – Dietmar Kühl Jun 25 '17 at 13:59

1 Answers1

3

_Ty(&)[] is a reference to a C-style array.

_Ty(*)[] is a pointer to a C-style array.

sh-
  • 941
  • 6
  • 13
  • 2
    *incomplete* C-style array. – StoryTeller - Unslander Monica Jun 25 '17 at 13:59
  • After googling with keyword `pointer to C-style array` I found a nice [post](http://cplusplus.bordoon.com/specializeForCharacterArrays.html#overloads) on its usage. The author only show its usage in his code sample without any explanation or referring to it. – David Lee Jun 25 '17 at 14:16
  • @StoryTeller Thanks u r my savior! I managed to find tons of information using the keyword `incomplete C-style array`. – David Lee Jun 26 '17 at 01:42