Storing function metadata
Prefer enum class with a name, and probably rename the enums, e.g. BOOL_TYPE becomes TYPE::BOOL or however you'd like to do the naming. Why do you want them to be an unnamed enum type?



You're printing an error to cout when there's an error. At the very least, print to cerr, so that someone running this might be able to filter output if they'd like to. I would personally either return a variant&lt;variable, error_message_type&gt; or throw an exception if there's an error like that though. Otherwise errors could easily slip through unnoticed.



This validation loop is inefficient and confusing.

Prefer extracting the conditional if possible. It appears to be ensuring that all the types are the same if it is a "VARIABLE_" type. Perhaps "variadic" may be more appropriate? 

    int idx = 0;
    for (auto i : list)
    {
        if ((indexes[0] &amp; 0x80) ? i.index() != (indexes[0] &amp; 0x03), idx++ : i.index() != indexes[idx++])
        {
            std::cout &lt;&lt; "Invalid argument type" &lt;&lt; std::endl;
            return variable(0);
        }
    }




indexes could take a type enum instead of int if it had a name. Why is it called indexes? You may be able to leverage more of std::variant and possibly not need the enum at all.



for (auto i : list) You probably want auto &amp; i, since this will result in string copies in the case of string variants.



return fn(std::forward&lt;decltype(list)&gt;(list));
This is unnecessary. std::forward is useful for templated types, but you know the type of list, it's a variableList &amp;&amp;. 

You could move the list, but I'm not sure that's what you really want.