2

I am trying to write sorting template function to make it work with custom classes.

My code is:

#include <iostream>
#include <vector>

struct test
{
    int value;
    test(int a) : value(a){};
    void print() { printf("the value is : %d", value); };
};

template <class T>
void bubblesort(T *m_data, size_t size, bool (*cmp)(const T &l, const T &r))
{
    for (uint32_t i = 0; i < size; i++)

        for (uint32_t j = 1; j < size - i; j++)

            if (cmp(m_data[j - 1], m_data[j]))
            {
                T temp = m_data[j];
                m_data[j] = m_data[j - 1];
                m_data[j - 1] = temp;
            }
}

int main()
{
    std::vector<test> arr;
    for (size_t i = 0; i < 10; i++)
        arr.emplace_back(i);

    std::vector<test *> arr1;
    for (auto &i : arr)
        arr1.emplace_back(&i);

    bubblesort<test>(&arr[0], arr.size(), [](const test &l, const test &r) { return l.value < r.value; });

    // bubblesort<test*>(&arr1[0], arr1.size(), [](const test *&l, const test *&r) { return l->value < r->value; });

    for (auto i : arr)
        printf("%d\n", i.value);
}

My question is how do you sort arr1 using the bubblesort function above? What kind of modification do I have to make in my code to be able to do so?

uncommenting the bubblesort line gives error

 error: invalid user-defined conversion from 'main()::<lambda(const test*&, const test*&)>' to 'bool (*)(test* const&, test* const&)' [-fpermissive]
[build]    48 |     bubblesort<test *>(&arr1[0], arr1.size(), [](const test *&l, const test *&r) { return l->value < r->value; });
9
  • 1
    There is no arr2 in your code. Commented Nov 12, 2020 at 11:13
  • sorry I corrected that in edit1. Commented Nov 12, 2020 at 11:14
  • Aside: arr.data() is preferred over &arr[0]. If you have any discretion about the parameters to bubblesort, consider templating on (forward) iterators Commented Nov 12, 2020 at 11:16
  • 1
    Would suggest to keep the interface kept tied to using .begin() and .end(). For types that are not standard containers (but are arrays that can be iterated over), begin(A) and end(A) works. Commented Nov 12, 2020 at 11:19
  • The line you commented out is almost correct, but remember that the type being sorted isn't test but test*. Commented Nov 12, 2020 at 11:19

2 Answers 2

5

Your function has the wrong type; T is test*, so you need test* const& - "reference to const pointer to test" - as the error message says.
(const test*& is "reference to pointer to const test.)

Sign up to request clarification or add additional context in comments.

Comments

2

Your solution cannot work with templates...it cannot deduce the parameters type.

Consider modifying your code as follow:

struct test
{
    int value;
    explicit test(int a) : value(a) {};
    void print() { printf("the value is : %d", value); };
};

template <class T, class _cmp>
void bubblesort(T *m_data, size_t size, _cmp cmp)
{
    for (uint32_t i = 0; i < size; i++)

        for (uint32_t j = 1; j < size - i; j++)

            if (cmp(m_data[j - 1], m_data[j]))
            {
                T temp = m_data[j];
                m_data[j] = m_data[j - 1];
                m_data[j - 1] = temp;
            }
}


int main()
{
    
    std::vector<test> arr;
    for (int i = 0; i < 10; i++)
        arr.emplace_back(i);

    
    std::vector<test *> arr1;
    for (auto i : arr)
        arr1.emplace_back(&i);

    bubblesort<test>(&arr[0], arr.size(), [](const test &l, const test &r) -> bool { return l.value < r.value; });
    bubblesort<test*>(&arr1[0], arr1.size(), [](const test* l, const test* r) -> bool { return l->value < r->value; });

    for (auto i : arr)
        printf("%d\n", i.value);
}

3 Comments

It is worth noting the pointers in arr1 point to expired a temporary variable and dereferencing such pointers in the lambda is UB.
@Qumby: yes, I didn't manage the problem with arr1 values..
how does this work? Does lambda get converted into some sort of class or something?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.