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 o código gerado por C++/WinRT deve usar essas classes; não as use em suas próprias funções e métodos.

Important

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. Observe, no entanto, que essa proteção não se estende a alterações feitas na coleção por outra thread. Impedir isso é sua responsabilidade.

Alternativas para parâmetros de cadeia de caracteres

winrt::param::hstring simplifica a passagem de parâmetros como winrt::hstring. Além de winrt::hstring, essas alternativas também são aceitas:

Alternativa Notes
{} Uma cadeia 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 terminada de nulo.

Você não pode passar nullptr para representar a cadeia de caracteres vazia. Em vez disso, use L"" ou {}.

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

Observe que os objetos std::wstring_view não são encerrados em nulo, mas C++/WinRT requer que o caractere após o final do modo de exibição seja nulo. Se você passar uma std::wstring_view não terminada em nulo, o processo será encerrado.

Alternativas para parâmetros iteráveis

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

As coleções Windows Runtime IVector<T> e IVectorView<T> já dão suporte a IIterable<T>. As coleções 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 Sync Async Notes
std::vector<T> const& Yes No
std::vector<T>&& Yes Yes O conteúdo é movido para um iterável temporário.
std::initializer_list<T> Yes Yes A versão assíncrona copia os itens.
std::initializer_list<U> Yes No U deve ser conversível em T.
{ begin, end } Yes No begin e end devem ser iteradores de avanço e *begin deve ser conversível para T.

O iterador duplo funciona de forma mais geral para o caso em que você tem uma coleção que não se encaixa em nenhum dos cenários acima, contanto que você possa iterar sobre ele e produzir coisas que podem ser convertidas em T. Por exemplo, você pode ter um IVector<U> ou 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 de 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 Sync Async Notes
std::map<K, V> const& Yes No
std::map<K, V>&& Yes Yes O conteúdo é movido para um iterável temporário.
std::unordered_map<K, V> const& Yes No
std::unordered_map<K, V>&&& Yes Yes O conteúdo é movido para um iterável temporário.
std::initializer_list<std::pair<K, V>> Yes Yes A versão assíncrona copia a lista para um iterável temporário.
{ begin, end } Yes No begin e end devem ser iteradores de avanço, e begin->first e begin->second devem ser conversíveis em K e V, respectivamente.

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

winrt::param::vector_view<T> e winrt::param::async_vector_view<T> simplificam a passagem de parâmetros como 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 Sync Async Notes
std::vector<T> const& Yes No
std::vector<T>&& Yes Yes O conteúdo é movido para uma exibição temporária.
std::initializer_list<T> Yes Yes A versão assíncrona copia a lista para uma exibição temporária.
{ begin, end } Yes No begin e end devem ser iteradores de avanço e *begin deve ser conversível para T.

Novamente, a versão com dois iteradores pode ser usada para criar visões de vetor a partir de elementos que não se encaixam em uma alternativa existente. A visualização temporária é mais eficiente se os iteradores begin e end forem iteradores de acesso aleatório.

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

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

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

Além de 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 Sync Async Notes
std::map<K, V> const& Yes No
std::map<K, V>&& Yes Yes O conteúdo é movido para uma exibição temporária.
std::unordered_map<K, V> const& Yes No
std::unordered_map<K, V>&&& Yes Yes O conteúdo é movido para uma exibição temporária.
std::initializer_list<std::pair<K, V>> Yes Yes O conteúdo é copiado para uma exibição temporária. As chaves podem não ser duplicadas.

Alternativas para parâmetros de vetor

winrt::param::vector<T> simplifica a passagem de parâmetros na forma de IVector<T>. Além do IVector<T>, essas alternativas também são aceitas:

Alternativa Notes
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

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

Você pode passar Notes
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

winrt::array_view<T> não está no namespace winrt::p aram , 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 Notes
{} 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 deve 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).

Veja também a postagem no blog Os vários padrões para passar matrizes de estilo C no limite da ABI Windows Runtime.