O seguinte não é compilado:
#include <memory>
#include <tuple>
#include <utility>
int main()
{
std::apply(std::make_unique<int>, std::make_tuple(1));
return 0;
}
Mensagem de erro:
In file included from /usr/include/c++/11/bits/unique_ptr.h:37,
from /usr/include/c++/11/memory:76,
from main.cpp:1:
/usr/include/c++/11/tuple: In instantiation of ‘constexpr decltype(auto) std::__apply_impl(_Fn&&, _Tuple&&, std::index_sequence<_Idx ...>) [with _Fn = std::unique_ptr<int, std::default_delete<int> > (&)(); _Tuple = std::tuple<int>; long unsigned int ..._Idx = {0}; std::index_sequence<_Idx ...> = std::integer_sequence<long unsigned int, 0>]’:
/usr/include/c++/11/tuple:1869:31: required from ‘constexpr decltype(auto) std::apply(_Fn&&, _Tuple&&) [with _Fn = std::unique_ptr<int, std::default_delete<int> > (&)(); _Tuple = std::tuple<int>]’
main.cpp:7:15: required from here
/usr/include/c++/11/tuple:1858:27: error: no matching function for call to ‘__invoke(std::unique_ptr > (&)(), std::__tuple_element_t<0, std::tuple >)’
1858 | return std::__invoke(std::forward<_Fn>(__f),
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
1859 | std::get<_Idx>(std::forward<_Tuple>(__t))...);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/tuple:41,
from /usr/include/c++/11/bits/unique_ptr.h:37,
from /usr/include/c++/11/memory:76,
from main.cpp:1:
/usr/include/c++/11/bits/invoke.h:90:5: note: candidate: ‘template constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...)’
90 | __invoke(_Callable&& __fn, _Args&&... __args)
| ^~~~~~~~
/usr/include/c++/11/bits/invoke.h:90:5: note: template argument deduction/substitution failed:
/usr/include/c++/11/bits/invoke.h: In substitution of ‘template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = std::unique_ptr<int, std::default_delete<int> > (&)(); _Args = {int}]’:
/usr/include/c++/11/tuple:1858:27: required from ‘constexpr decltype(auto) std::__apply_impl(_Fn&&, _Tuple&&, std::index_sequence<_Idx ...>) [with _Fn = std::unique_ptr<int, std::default_delete<int> > (&)(); _Tuple = std::tuple<int>; long unsigned int ..._Idx = {0}; std::index_sequence<_Idx ...> = std::integer_sequence<long unsigned int, 0>]’
/usr/include/c++/11/tuple:1869:31: required from ‘constexpr decltype(auto) std::apply(_Fn&&, _Tuple&&) [with _Fn = std::unique_ptr<int, std::default_delete<int> > (&)(); _Tuple = std::tuple<int>]’
main.cpp:7:15: required from here
/usr/include/c++/11/bits/invoke.h:90:5: error: no type named ‘type’ in ‘struct std::__invoke_result > (&)(), int>’
Como isso pode ser consertado?
C++17 e anteriores
std::make_unique<int>
tem o tipostd::unique_ptr<int>()
que é uma função que retorna astd::unique_ptr<int>
e não aceita parâmetros. Não é isso que você deseja, pois está passando um valor para a função.O que você precisa é
std::make_unique<int, int>
que tenha o tipostd::unique_ptr<int>(int)
que você deseja. O primeiro parâmetro do modelo é para o tipo deunique_ptr
e cada tipo adicional é para os tipos de argumento da função make.C++20+
Como C++20
make_unique
não é uma função endereçável, você não tem mais permissão para usar essa técnica em código portátil. Em vez disso, você precisará aproveitar um lambda para um nível de indireção como