简体   繁体   中英

C++17 class template partial deduction

My understanding about the Template argument deduction for class templates proposal was to homogenize the behaviour of template functions and template classes in deduction contexts. But I think that I have misunderstood something.

If we have this template object:

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 main()
{
    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

    std::cout << a.size << b.size << c.size;

    return 0;
}

The code above outputs 555 as expected. I've tried the same in Wandbox using the newer compiler setup 1 :

int main()
{
    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.

    std::cout << a.size << b.size << c.size;

    return 0;
}

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


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

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

There appears to be a contradiction here. Looking at P0091R3 , it seems clear that partially specifying parameters is supposed to be allowed:

We propose to allow a template name referring to a class template as a simple-type-specifier or with partially supplied explicit template arguments in two contexts:

But the actual standards wording in the same proposal does not provide a way to handle "partially supplied explicit template arguments". template-name as a simple-type-specifier is not allowed to have template arguments.

So following the specification itself, the compiler's behavior appears to be correct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM