Silicomancer
Silicomancer

Reputation: 9166

Additional type in template deduction guide

This snippet demonstrates how to use deduction guides to allow source_location::current together with parameter packs (see 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...>;

Which is used like this:

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

Now I want to extend the struct Test by an additional Type T that shall be specified explicitly. I tried the following but the deduction guide is not accepted:

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...>;

Compiler says:

deduction guide template contains a template parameter that cannot be deduced.

I need the additional T to allow struct Test to internally build an object of a user specified type.

It should be used like this:

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

Is it possible to define a deduction guide including the additional T?

Upvotes: 3

Views: 1558

Answers (1)

Barry
Barry

Reputation: 302932

You cannot do it in this syntax:

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

Because there is no such thing as "partial" class template argument deduction. It's all or nothing - you either specify all the class template parameters or none of the class template parameters.

However, you can just move the type over:

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

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

And now you deduced the type. You can even write the deduction guide to require this usage:

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

Although Test's constructor still needs to take a type_t<T> argument first.

Upvotes: 4

Related Questions