Passando parâmetros para APIs projetadas

Para determinados tipos, o C++/WinRT fornece métodos alternativos para passar um parâmetro para uma API projetada. Essas classes de aceitação de parâmetros são colocadas no namespace winrt::p aram. Somente um código gerado por C++/WinRT deve usar essas classes, não use elas nas suas funções e métodos.

Importante

Não use os tipos no namespace winrt::param por conta própria. Eles têm a finalidade de beneficiar a projeção.

Algumas dessas alternativas distinguem entre chamadas síncronas e assíncronas. A versão para chamadas assíncronas normalmente assume a propriedade dos dados do parâmetro para garantir que os valores permaneçam válidos e inalterados até que a chamada assíncrona seja concluída. No entanto, observe que essa proteção não se estende a alterações na coleção de outro thread. Impedir isso é sua responsabilidade.

Alternativas para parâmetros de cadeia de caracteres

O winrt::p aram::hstring simplifica os parâmetros de passagem como o winrt::hstring. Além do winrt::hstring, essas alternativas também são aceitas:

Alternativa Observações
{} Uma sequência de caracteres vazia.
std::wstring_view O modo de exibição deve ser seguido por um terminador nulo.
std::wstring
wchar_t const* Uma cadeia de caracteres terminada em nulo.

Você não pode passar nullptr para representar a cadeia de caracteres vazia. Use L"" ou {}.

O compilador sabe como avaliar wcslen em literais de cadeia de caracteres em tempo de compilação. Portanto, para literais, L"Name"sv e L"Name" são equivalentes.

Observe que objetos std::wstring_view não são terminados em nulo, mas o C++/WinRT exige que o caractere após o final da cadeia de caracteres seja nulo. Se você passar uma std::wstring_view não terminada em nulo, o processo será encerrado.

Alternativas para parâmetros iteráveis

O winrt::param::iterable<T> e o winrt::param::async_iterable<T> simplificam a passagem de parâmetros como o IIterable<T>.

As coleções IVector<T> e IVectorView<T> do Windows Runtime já dão suporte a IIterable<T>. As coleções do Windows Runtime IMap<K, V> e IMapView<K, V> já dão suporte a IIterable<IKeyValuePair<K, V>>.

Além do IIterable<T>, as alternativas a seguir também são aceitas. Observe que algumas alternativas estão disponíveis apenas para métodos síncronos.

Alternativa Sincronização Async Observações
std::vector<T> const& Sim Não
std::vector<T>&& Sim Yes O conteúdo é movido para um iterável temporário.
std::initializer_list<T> Sim Yes A versão assíncrona copia os itens.
std::initializer_list<U> Sim Não Deve ser possível converter U em T.
{ begin, end } Sim Não begin e end deve ser iteradores de encaminhamento e *begin deve ser conversível para T.

O iterador duplo funciona de maneira mais geral no caso em que você tem uma coleção que não se encaixa em nenhum dos cenários acima, desde que você possa iterar nele e produzir coisas que possam ser convertidas em T. Por exemplo, você pode ter um IVector<U> ou um std::vector<U>, em que U é conversível para T.

No exemplo a seguir, o método SetStorageItems espera um IIterable<IStorageItem>. O padrão de iterador duplo nos permite passar outros tipos de coleções.

// IVector of derived types.
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Storage::StorageFile>
    storageFiles{ /* initialization elided */ };
dataPackage.SetStorageItems(storageFiles); // doesn't work
dataPackage.SetStorageItems({ storageFiles.begin(), storageFiles.end() }); // works

// Array of derived types.
std::array<winrt::Windows::Storage::StorageFile, 3>
    storageFiles{ /* initialization elided */ };
dataPackage.SetStorageItems(storageFiles); // doesn't work
dataPackage.SetStorageItems({ storageFiles.begin(), storageFiles.end() }); // works

Para o caso do IIterable<IKeyValuePair<K, V>>, as alternativas a seguir são aceitas. Observe que algumas alternativas estão disponíveis apenas para métodos síncronos.

Alternativa Sincronização Async Observações
std::map<K, V> const& Sim Não
std::map<K, V>&& Sim Yes O conteúdo é movido para um iterável temporário.
std::unordered_map<K, V> const& Sim Não
std::unordered_map<K, V>&& Sim Yes O conteúdo é movido para um iterável temporário.
std::initializer_list<std::pair<K, V>> Sim Yes A versão assíncrona copia a lista em uma iterável temporária.
{ begin, end } Sim Não begin e end devem ser iteradores de encaminhamento, e begin->first e begin->second devem ser conversíveis para K e V, respectivamente.

Alternativas para parâmetros de exibição de vetor

O winrt::param::vector_view<T> e o winrt::param::async_vector_view<T> simplificam a passagem de parâmetros como o IVectorView<T>.

Você pode chamar IVector<T>::GetView para obter um IVectorView<T> de um IVector<T>.

Além do IVectorView<T>, as alternativas a seguir também são aceitas. Observe que algumas alternativas estão disponíveis apenas para métodos síncronos.

Alternativa Sincronização Async Observações
std::vector<T> const& Sim Não
std::vector<T>&& Sim Yes O conteúdo é movido para uma exibição temporária.
std::initializer_list<T> Sim Yes A versão assíncrona copia a lista para uma exibição temporária.
{ begin, end } Sim Não begin e end devem ser iteradores de encaminhamento e *begin deve ser conversível para T.

Novamente, a versão do iterador duplo pode ser usada para criar exibições de vetor de itens que não se encaixam em uma alternativa existente. A exibição temporária será mais eficiente se os iteradores begin e end forem iteradores de acesso aleatório.

Alternativas para parâmetros de exibição de mapa

O winrt::param::map_view<T> e o winrt::param::async_map_view<T> simplificam a passagem de parâmetros como o IMapView<T>.

Você pode chamar IMap<K, V>::GetView para obter um IMapView<K, V> de um IMap<K, V>.

Além do IMapView<K, V>, as alternativas a seguir também são aceitas. Observe que algumas alternativas estão disponíveis apenas para métodos síncronos.

Alternativa Sincronização Async Observações
std::map<K, V> const& Sim Não
std::map<K, V>&& Sim Yes O conteúdo é movido para uma exibição temporária.
std::unordered_map<K, V> const& Sim Não
std::unordered_map<K, V>&& Sim Yes O conteúdo é movido para uma exibição temporária.
std::initializer_list<std::pair<K, V>> Sim Yes O conteúdo é copiado para uma exibição temporária. As chaves não podem ser duplicadas.

Alternativas para parâmetros de vetor

O winrt::p aram::vector<T> simplifica a passagem de parâmetros como o IVector<T>. Além do IVector<T>, essas alternativas também são aceitas:

Alternativa Observações
std::vector<T>&& O conteúdo é movido para um vetor temporário. Os resultados não são movidos de volta.
std::initializer_list<T>

Se o método alterar o vetor temporário, essas alterações não serão refletidas nos parâmetros originais. Para observar as alterações, passe um IVector<T>.

Alternativas para parâmetros de mapa

O winrt::p aram::map<K, V> simplifica a passagem de parâmetros como o IMap<K, V>. Além do IMap<K, V>, essas alternativas também são aceitas:

Você pode passar Observações
std::map<K, V>&& O conteúdo é movido para um mapa temporário. Os resultados não são movidos de volta.
std::unordered_map<K, V>&& O conteúdo é movido para um mapa temporário. Os resultados não são movidos de volta.
std::initializer_list<std::pair<K, V>>

Se o método alterar o mapa temporário, essas alterações não serão refletidas nos parâmetros originais. Para observar as alterações, passe um IMap<K, V>.

Alternativas para parâmetros de matriz

O winrt::array_view<T> não está no namespace winrt::param, mas é usado para parâmetros que são matrizes de estilo C. Além de um array_view<T>explícito, essas alternativas também são aceitas:

Alternativa Observações
{} Matriz vazia.
U[] Uma matriz de estilo C, onde U é conversível para T e sizeof(U) == sizeof(T).
std::array<U, N> Onde U é conversível para T e sizeof(U) == sizeof(T).
std::vector<U> Onde U é conversível para T e sizeof(U) == sizeof(T).
{ begin, end } begin e end devem ser do tipo T*, representando o intervalo [begin, end).
std::initializer_list<T>
std::span<U, N> Onde U é conversível para T e sizeof(U) == sizeof(T).

Confira também a postagem no blog Os vários padrões para transmitir matrizes em estilo C entre o limite do ABI do Windows Runtime.