#include <iostream>
#include <vector>


/**
 *  This is a helper class.
 *  It can be used only inside the function ListInitializer list(Args&& ...args)
 *  ListInitializer list(Args&& ...args)
 *  In all other cases, use it not possible
 */	
class ListInitializer
{
public:

    /**
     *  Assignment operator
     *	Ref-qualified forbids such things:
     *	ListInitializer c(a,b);
     *	c = arr;
     *	You can only use this form:
     *	ListInitializer(a,b) = arr;
     */
    ListInitializer &operator=(std::vector<std::string> &arr) && // <-- Ref-qualified
    {
        unsigned int min = (size < arr.size()) ? size : arr.size();
        for(unsigned int i = 0; i < min; i++)
        {
            *parr[i] = arr[i];
        }
    }

    /**
     *  Deleted constructors. Forbids such things:
     *	list q(a,b,c,d,e),w(a,b,c,d,e);
     *	w = q;
     *	You can only use this form:
     *	list(a,b,c,d,e) = arr;
     */
    ListInitializer(const ListInitializer &that) = delete;
    ListInitializer() = delete;

    ~ListInitializer()
    {
        if(parr) delete [] parr;
    }

private:
    /**
     *  Constructor with one argument
     */
    explicit ListInitializer(std::string& arg)
    {
        size = 1;
        parr = new std::string*[1];
        helper(0, arg);
    }

    /**
     *  Constructor with a variable (>1) number of arguments
     *	You can use any number of arguments of type std::string in the constructor.
	 *	list(a,b,c,d) = arr;
	 *	list(a,b) = arr;
     */
    template <typename ...Args>
    ListInitializer(std::string& arg0, Args&... args)
    {
        size = sizeof...(Args)+1;
        parr = new std::string*[size];
        helper(0, arg0, args...);
    }

private:

    /**
     *  Move constructor
     */
    ListInitializer(ListInitializer &&that) : parr(that.parr),size(that.size)
    {
    	that.parr = nullptr;
    }

    /**
     *  Helper method.
     *	Allows to initialize the list of any number of arguments.
	 *	Alternately, one by one makes pointers to the arguments into the internal array.
     */
    template <typename ...Args>
    void helper(int ind, std::string& arg0, Args&... args)
    {
        helper(ind, arg0);
        helper(++ind, args...);
    }

    /**
     *  Helper method.
     */
    void helper(int ind, std::string& arg0)
    {
        parr[ind] = &arg0;
    }
    
    template <typename ...Args>
    friend ListInitializer list(Args& ...args);
    
    // Internal array of pointers to pointers to arguments
    std::string **parr;
    // The number of arguments with which the constructor was called
    unsigned int size;
};


template <typename ...Args>
ListInitializer list(Args& ...args)
{
    return ListInitializer(args...);
}


int main(){
	
    std::vector<std::string> arr{"str1","str2","str3","str4","str5","str6"};
    std::string a,b,c,d,e;
    
    list(b) = arr;
    std::cout << std::endl << a << " " << b << " " << c << " " << d << " " << e << std::endl;

    list(a,b,c,d,e) = arr;
    std::cout << std::endl << a << " " << b << " " << c << " " << d << " " << e << std::endl;

    return 0;
};
