c++templatesc++17template-argument-deductionctad

Why is partial class template argument deduction impossible?


My understanding about the P0091: Template argument deduction for class templates proposal was to homogenize the behavior of function templates and class templates in deduction contexts, but I think that I have misunderstood something.

If we have this class template:

template <std::size_t S, typename T>
struct test
{
    static constexpr auto size = S;
    using type_t = T;

    test(type_t (&input)[size]) : data(input) {}
    type_t (&data)[size]{};
};

I tend to use a helper function as syntactic sugar for creating test objects:

template <std::size_t S, typename T>
test<S, T> helper(T (&input)[S]) { return input; }

Which can be used as shown below:

int buffer[5];

auto a = helper<5, int>(buffer); // No deduction
auto b = helper<5>(buffer);      // Type deduced
auto c = helper(buffer);         // Type and size deduced

The code above compiles. I've tried the same in Wandbox using the newer compiler setup1:

int buffer[5];

test<5, int> a(buffer); // No deduction: OK.
test<5> b(buffer);      // Type deduced: FAILS.
test c(buffer);         // Type and size deduced: OK.

It looks like template argument deduction for class templates works only deducing all the parameters. I was expecting both behaviors (helper function and class template) to be the same; have I misunderstood something?


1The last compilers availables in Wandbox are gcc HEAD 7.0.1 201701 and clang HEAD 5.0.0 (trunk).


Solution

  • From this excellent trip report by Botond Ballo:

    The feature as originally proposed included a provision for partial deduction, where you explicitly specify some of the template arguments, and leave the rest to be deduced, but this was pulled over concerns that it can be very confusing in some cases:

    // Would have deduced tuple<int, string, float>,
    // but tuple<int> is a well-formed type in and of itself!
    tuple<int> t(42, "waldo", 2.0f);