boolinq icon indicating copy to clipboard operation
boolinq copied to clipboard

Non-copyable types of elements are not supported

Open AStepaniuk opened this issue 8 years ago • 7 comments

This will not work:

std::vector<std::unique_ptr<MyType>> myVector;
boolinq::from(xmlLogicFragments)
    .select([](const auto& uniquePtr) { return uniquePtr.get(); })
    .toVector();

I.e. conversion from the vector of the unique ptrs to the vector of raw ptrs does not work. The vector of unique ptrs is convenient to have RAII for the collection of items, as it is suggested e.g. here http://stackoverflow.com/questions/27460377/why-is-using-vector-of-pointers-considered-bad

Also there are possible the other situations, when non-copyable elements can be used.

Would that be possible if boolinq is working with the references to the elements in such cases instead?

AStepaniuk avatar Dec 09 '16 12:12 AStepaniuk

Do you have compilation or execution problems with following code sample? I can't check it right now.

k06a avatar Dec 09 '16 12:12 k06a

It produces compilation error.

In the code:

template<typename T, typename TI>
LinqObj<Enumerator<T,TI> > from(TI begin, TI end)
{
    return Enumerator<T,TI>([=](TI & iter){
        return (iter == end) ? throw EnumeratorEndException() : *(iter++);   // <<< here the error occurs
    }, begin);
}

The error message is:

Error C2280 'std::unique_ptr<MyType,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function \lib\boolinq\boolinq\boolinq.h 734

As I see it, Enumerator<T,TI>() constructor takes 2nd parameter by value, i.e. wants the copy of the parameter. That won't compile if parameter is non-copyable. That is the case for unique_ptr.

Another similar issue here is that lambda wants to return *(iter++). That requires copying the return value.

It seems to me that working with the references would work here. I'm not sure though as I had no chance to get the lib working with references.

AStepaniuk avatar Dec 09 '16 13:12 AStepaniuk

@AStepaniuk some methods work by copying elements in data structures like set/map. How do you think to deal with them?

k06a avatar Dec 08 '17 14:12 k06a

@AStepaniuk just rolled out new version 3.0.0 and started experimenting with unique_ptr: https://github.com/k06a/boolinq/pull/29

k06a avatar Jul 02 '19 14:07 k06a

Will this ever be solved here?

Gargony avatar May 21 '21 08:05 Gargony

@Gargony not sure, any ideas on the solution?

k06a avatar May 21 '21 15:05 k06a

@k06a Linq on c++ is most hardly, but when I was make my own implementation non-copyable type and no virtual methods it was first priority. TDD was start from this requires.

I solved it through std::ref Somthing like this:

std::vector<std::unique_ptr<MyType>> myVector;
linq::From(myVector)
    .Select<const MyType&>([](const auto& uniquePtr) { return std::ref(*uniquePtr.get()); })

Here you cannot use vector, because vector not supports refs. But you can use pointers

std::vector<std::unique_ptr<MyType>> myVector;
std::vector<const MyType*> myVector2 =
linq::From(myVector)
    .Select<const MyType*>([](const auto& uniquePtr) { return uniquePtr.get(); })
    .ToVector();

for changes:

std::vector<std::unique_ptr<MyType>> myVector;
std::vector<MyType*> myVector2 =
linq::From(myVector)
    .Select<MyType*>([](auto& uniquePtr) { return uniquePtr.get(); })
    .ToVector();

Gargony avatar May 24 '21 03:05 Gargony