Тип вычета параметра и пакета параметров - PullRequest
0 голосов
/ 28 января 2020

У меня есть следующий код для общего переноса объектов Pets c в unique_ptr, но он не совсем работает так, как я ожидал от документации cppreference по выводу типа шаблона: https://en.cppreference.com/w/cpp/language/class_template_argument_deduction.

template <typename obj_type, typename... constructor_args>
using petsc_cons = PetscErrorCode (*)(constructor_args..., obj_type *);

template <typename obj_type> using petsc_destr = PetscErrorCode (*)(obj_type *);

template <typename obj_type, typename... constructor_args>
auto petsc_make_unique(petsc_cons<obj_type, constructor_args...> construct,
                       petsc_destr<obj_type> destroy, constructor_args... args) {
  // allocation code...
}

class NLOptimizer {
public:
  NLOptimizer(const size_t num_vars)
      : tao_ctx(petsc_make_unique<Tao>(TaoCreate, TaoDestroy,
                                       PETSC_COMM_SELF)) {}

Сбой на g ++:

autodiff_tao.hpp: In constructor ‘auto_diff::optimize_tao::NLOptimizer<expr_t>::NLOptimizer(expr_t, size_t)’:
autodiff_tao.hpp:45:62: error: no matching function for call to ‘petsc_make_unique<Tao>(PetscErrorCode (&)(MPI_Comm, _p_Tao**), PetscErrorCode (&)(_p_Tao**), MPI_Comm)’
   45 |                                               PETSC_COMM_SELF)) // ,
      |                                                              ^
autodiff_tao.hpp:24:6: note: candidate: ‘template<class obj_type, class ... constructor_args> auto auto_diff::optimize_tao::petsc_make_unique(auto_diff::optimize_tao::petsc_cons<obj_type, constructor_args ...>, auto_diff::optimize_tao::petsc_destr<obj_type>, constructor_args ...)’
   24 | auto petsc_make_unique(petsc_cons<obj_type, constructor_args...> construct,
      |      ^~~~~~~~~~~~~~~~~
autodiff_tao.hpp:24:6: note:   template argument deduction/substitution failed:
autodiff_tao.hpp:45:62: note:   mismatched types ‘_p_Tao*’ and ‘ompi_communicator_t’
   45 |                                               PETSC_COMM_SELF)) // ,

Clang может определить типы пакетов параметров и скомпилировать приведенный выше код. Это ошибка в g ++, clang, или я полагаюсь на неопределенное поведение здесь?

Я пытался выполнить эту компиляцию на нескольких минорных версиях clang 9 и g ++ 9 и нескольких менее удачных вариантах кода выше .

1 Ответ

0 голосов
/ 28 января 2020

Похоже, g cc пытается вывести constructor_args из construct, и выводит их как пустой пакет параметров.

Чтобы просто вывести его из constructor_args... args, просто поместите его в не выводимом контексте (как std::type_identity_t<petsc_cons<obj_type, constructor_args...>> construct). Вы должны убедиться, что constructor_args... args точно соответствует.

...