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 | No | |
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 | No | |
std::map<K, V>&& | Sim | Yes | O conteúdo é movido para um iterável temporário. |
std::unordered_map<K, V> const& | Sim | No | |
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 | No | |
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 | No | |
std::map<K, V>&& | Sim | Yes | O conteúdo é movido para uma exibição temporária. |
std::unordered_map<K, V> const& | Sim | No | |
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.