Search code examples
c++classconstructorvariadic-templatesperfect-forwarding

How to construct a class from a pack in C++?


I am trying to initialize a class with a pack passed as an argument to my function. Here is what I got so far:

struct Vec3
{
    float x, y, z;
};

template<typename _Ty, typename... Args>
__forceinline _Ty construct_class(Args&&... arguments)
{
    return _Ty(arguments...);
}

// here I am trying to construct a Vec3 by calling construct_class
Vec3 vec = construct_class<Vec3>(10.f, 20.f, 30.f);

Unfortunately I get the following compiler error in visual studio: C2440 '<function-style-cast>': cannot convert from 'initializer list' to '_Ty'

I have seen people doing this:

template<typename _Ty, typename... Args>
__forceinline _Ty construct_class(Args&&... arguments)
{
    return _Ty(std::forward<Args>(arguments)...);
}

But this also doesn't work for me, I get the exact same compiler error as before.

So my question is how should I use the pack/intializer list inside construct_class to construct the _Ty class (in this case Vec3)? I am not familiar with packs in C++.


Solution

  • You could replace return _Ty(arguments...) with return _Ty{arguments...} as shown below:

    //---------------v--------------------- v----->removed the underscore
    template<typename Ty, typename... Args>  Ty construct_class(Args&&... arguments)
    {
    //-----------v------------v------------------->used curly braces instead of parenthesis
        return Ty{arguments...};
    }
    

    Working Demo


    Also, note that the given program will work with C++20 without having to use curly braces.


    Also, What are the rules about using an underscore in a C++ identifier? might come in handy when using leading underscore for names.