Search code examples
uwpc++-winrt

How to use the ReplaceAll method of IVector to transfer data from one IVector to another?


I have 2 IVectors and I would like to replace all of the content of one for the content of the other. The ReplaceAll method seems like it might work.

So I tried the following:

IVector<IInspectable> my_ivector1 = winrt::single_threaded_vector<IInspectable>({ box_value(L"whatever1") });
IVector<IInspectable> my_ivector2 = winrt::single_threaded_vector<IInspectable>({ box_value(L"whatever2") });
std::array<const IInspectable, 1> arrv{ box_value(L"result") };

my_ivector2.ReplaceAll(arrv);
auto res = unbox_value<hstring>(my_ivector2.GetAt(0)); // This works, res == L"result". The content of my_ivector2 was replaced by the content of arrv. 

my_ivector2.ReplaceAll(my_ivector1); // compilation error

The compilation error:

cannot convert argument 1 from 'winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Foundation::IInspectable>' to 'winrt::array_view<const winrt::Windows::Foundation::IInspectable>'

I expected to be able to use ReplaceAll to replace all the content of one IVector with the content of another IVector. Is ReplaceAll not the right method to do this?


Solution

  • Since you're using the C++ WinRT type, and not a projected vector, in your simple example above you can get a reference to the underlying std::vector using get_container(). You'd need to change your variable types to auto instead of IVector<>. From there, you can move or copy elements from one vector to the other using any standard library technique you like as appropriate. Simple value assignment should suffice to copy the contents. E.g.

    my_ivector2.get_container() = my_ivector1.get_container();

    If you're trying to work with WinRT vectors where they're not known to be your C++ /WinRT implementations, then you'll need to copy the values using an array_view.

    An array_view and vector aren't interchangeable, as much as it seems like they should be. They provide slightly different semantics and guarantees. You would need to use GetMany on the first container to load the values into something like a std::vector resized to the container size, then call ReplaceAll with the second container.

    Ben