Template argument deduction template for a constructor with parameters that depend on an integer template

I found the code at StackOverflow question and answer and I'll try It works, but I don't quite understand what's going on there.

I have duplicated code from this link below:

template <size_t N, class = std::make_index_sequence<N>>
class Vector;

template <size_t N, size_t... Is>
class Vector<N, std::index_sequence<Is...>> 
{
private:
    std::array<double, N> vals;

    template <size_t >
    using double_ = double;
public:
    Vector(double_<Is>... vals)
    {
        ...
    }
};

      

For example, we are trying to use it like this:

Vector<3> a(1.0, 2.0, 3.0);

      

How does type inference work?

ps As far as I understand, when the compiler sees this line, first of all, it tries to infer types for specialization. It outputs N

as 3 and Is

as an empty sequence and then fails when it cannot find a matching constructor. The general pattern is not defined, so compilers must fail as well. But what happens next?

+3


source to share


1 answer


This part declares (does not define) a default specialization of the Vector template class. The second template argument by default matches the index sequence 0 ... N-1

template <size_t N, class = std::make_index_sequence<N>>
class Vector;

      

The default argument is important because it serves to present a simple interface and hide the complexities of the next specialization ...

This specialization is the one resulting from the above default declaration. The purpose of the index sequence is to carry over the variation sequence Is

(i.e. 0 ... N

-1).

template <size_t N, size_t... Is>
class Vector<N, std::index_sequence<Is...>> 
{

      

Determines sufficient storage



private:
    std::array<double, N> vals;

      

Provides a means of converting a sequence Is

from size_t to a type (in this case double)

    template <size_t >
    using double_ = double;

public:

      

Defines a constructor for adoption double_<0>

, double_<1>

... double_<N-1>

. But double<N>

for any N

is the typedef of double

. So what this line does is provide a constructor that takes one double

for each Is

. that is, as many doublings as it takes to build the array. It's pretty smart.

    Vector(double_<Is>... vals)
    {
        ...
    }
};

      

+1


source







All Articles