Passando parâmetros para APIs projetadas

Para certos tipos, o C++/WinRT fornece métodos alternativos para passar um parâmetro para uma API projetada. Estas classes que aceitam argumentos são definidas no espaço de nomes winrt::param. Apenas o código gerado por C++/WinRT deve usar estas classes; Não os uses nas tuas próprias funções e métodos.

Important

Não deves usar tu mesmo os tipos no espaço de nomes winrt::param. São para benefício da projeção.

Algumas destas 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 permanecem válidos e inalterados até que a chamada assíncrona seja concluída. Note-se, no entanto, que esta proteção não se estende a alterações na coleção provenientes de outro tópico. Prevenir isso é da tua responsabilidade.

Alternativas para parâmetros de cadeia

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

Alternativa Notes
{} Uma cadeia de caracteres vazia.
STD::wstring_view A vista deve ser seguida por um terminador nulo.
std::wstring
wchar_t const* Uma cadeia com terminação nula.

Não podes passar nullptr para representar a corda vazia. Em vez disso, use L"" ou {}.

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

Note que os objetos std::wstring_view não são terminados por null, mas o C++/WinRT exige que o carácter após o fim da vista seja um null. Se passar um std::wstring_view sem terminação nula, então o processo termina.

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 de Windows Runtime IVector<T> e IVectorView<T>suportam IIterable<T>. As coleções do Windows Runtime IMap<K, V> e IMapView<K, V> já suportam IIterable<IKeyValuePair<K, V>>.

Além de IIterable<T>, também são aceites as seguintes alternativas. Note que algumas alternativas estão disponíveis apenas para métodos síncronos.

Alternativa Sincronização Assíncrono 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 O U deve ser convertível para T.
{ begin, end } Yes No begin e end devem ser iteradores diretos, e *begin devem ser convertíveis para T.

O iterador duplo funciona de forma mais geral no caso em que tens uma coleção que não se enquadra em nenhum dos cenários acima, desde que consigas iterar sobre ela e produzir coisas que possam ser convertidas em T. Por exemplo, pode ter um IVector<U> ou um vetor<> std::, onde U é convertível em T.

No exemplo seguinte, o método SetStorageItems requer um IIterable<IStorageItem>. O padrão de iterador duplo permite-nos 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

No caso do IIterable<IKeyValuePair<K, V>>, aceites as seguintes alternativas. Note que algumas alternativas estão disponíveis apenas para métodos síncronos.

Alternativa Sincronização Assíncrono 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 diretos, e begin->first e begin->second devem ser convertíveis em K e V, respetivamente.

Alternativas para parâmetros de vista vetorial

winrt::param::vector_view<T> e winrt::param::async_vector_view<T> simplificam a passagem de parâmetros na forma de IVectorView<T>.

Pode chamar IVector<T>::GetView para obter um IVectorView<T> a partir de um IVector<T>.

Além do IVectorView<T>, também são aceites as seguintes alternativas. Note que algumas alternativas estão disponíveis apenas para métodos síncronos.

Alternativa Sincronização Assíncrono Notes
std::vector<T> const& Yes No
std::vector<T>&& Yes Yes O conteúdo é movido para uma vista temporária.
std::initializer_list<T> Yes Yes A versão assíncrona copia a lista para uma vista temporária.
{ begin, end } Yes No begin e end devem ser iteradores diretos, e *begin devem ser convertíveis para T.

Mais uma vez, a versão de iterador duplo pode ser usada para criar vistas vetoriais a partir de coisas que não se encaixam numa alternativa existente. A vista temporária é mais eficiente se os iteradores begin e end forem iteradores de acesso aleatório.

Alternativas para parâmetros de visualização do mapa

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

Pode chamar IMap<K, V>::GetView para obter um IMapView<K, V> de um IMap<K, V>.

Além do IMapView<K, V>, as seguintes alternativas também são aceites. Note que algumas alternativas estão disponíveis apenas para métodos síncronos.

Alternativa Sincronização Assíncrono Notes
std::map<K, V> const& Yes No
std::map<K, V>&& Yes Yes O conteúdo é movido para uma vista temporária.
std::unordered_map<K, V> const& Yes No
std::unordered_map<K, V>&& Yes Yes O conteúdo é movido para uma vista temporária.
std::initializer_list<std::pair<K, V>> Yes Yes O conteúdo é copiado para uma vista temporária. As chaves não podem ser duplicadas.

Alternativas para parâmetros vetoriais

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

Alternativa Notes
std::vector<T>&& O conteúdo é movido para um vetor temporário. Os resultados não são movidos para trás.
std::initializer_list<T>

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

Alternativas para parâmetros do mapa

winrt::param::map<K, V> simplifica a passagem de parâmetros na forma de IMap<K, V>. Além do IMap<K, V>, estas alternativas também são aceites:

Podes passar Notes
std::map<K, V>&& O conteúdo é transferido para um mapa temporário. Os resultados não são movidos de volta.
std::unordered_map<K, V>&& O conteúdo é transferido 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 mutar o mapa temporário, então essas alterações não se refletem 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 arrays ao estilo C. Para além de um array_view<explícito T>, estas alternativas também são aceites:

Alternativa Notes
{} Matriz vazia.
U[] Um array ao estilo C, onde U é convertível em T, e sizeof(U) == sizeof(T).
std::array<U, N> Onde U é convertível em T, e sizeof(U) == sizeof(T).
std::vector<U> Onde U é convertível em 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 é convertível em T, e sizeof(U) == sizeof(T).

Veja também a publicação no blogue Os vários padrões para passar arrays de estilo C através do limite da ABI do Windows Runtime.