Дополнительный тип в шаблоне руководства по выводу - PullRequest
1 голос
/ 21 октября 2019

Этот фрагмент демонстрирует, как использовать направляющие вычеты для разрешения source_location::current вместе с пакетами параметров (см. https://stackoverflow.com/a/57548488/1421332):

template <typename... Params>
struct Test
{
   Test(Params&&... params,
        const std::source_location& loc = std::source_location::current());
};

template <typename ...Params>
Test(Params&&...) -> Test<Params...>;

, который используется следующим образом:

Test(5, 'A', 3.14f, "foo");

сейчасЯ хочу расширить структуру Test дополнительным типом T, который должен быть указан явно. Я попробовал следующее, но руководство по выводу не принято:

template <typename T, typename... Params>
struct Test
{
    Test(Params&&... params,
         const std::source_location& loc = std::source_location::current());
};

template <typename T, typename ...Params>
Test(Params&&...) -> Test<T, Params...>;

Компилятор говорит:

шаблон руководства по выводу содержит параметр шаблона, который не может быть выведен.

Мне нужен дополнительный T, чтобы позволить struct Test внутренне построить объект указанного пользователем типа.

Itследует использовать следующим образом:

Test<MyType>(5, 'A', 3.14f, "foo");

Можно ли определить руководство по удержанию, включая дополнительный T?

1 Ответ

3 голосов
/ 21 октября 2019

Вы не можете сделать это в следующем синтаксисе:

Test<MyType>(5, 'A', 3.14f, "foo");

Поскольку не существует такого понятия, как «частичный» вывод аргумента шаблона класса. Это все или ничего - вы либо указываете все параметры шаблона класса, либо нет параметров шаблона класса.

Однако вы можете просто переместить тип поверх:

template <typename T> struct type_t {};
template <typename T> inline type_t<T> type{};

Test(type<MyType>, 5, 'A', 3.14f, "foo");

А теперь вы вывели тип. Вы даже можете написать руководство по выводу, чтобы потребовать такого использования:

template <typename T, typename ...Params>
Test(type_t<T>, Params&&...) -> Test<T, Params...>;

Хотя конструктору Test все еще нужно сначала принять аргумент type_t<T>.

...