Storing function metadata In a project, we have a file that contains something like a script which we need to parse. At the moment the validation is tough since we have an array of functions returing variable and taking variableList (basically std::variant&lt;&gt;and vector of variants, see definition below)
I am trying to have function metadata available (number of input arguments and its type, possibly return value type for validating the input "script". I would like to replace std::function with something like this:

using variable = std::variant&lt;bool, int, double, std::string&gt;;
using variableList = std::vector&lt;variable&gt;;

enum {
    BOOL_TYPE = 0,
    INT_TYPE = 1,
    DOUBLE_TYPE = 2,
    STRING_TYPE = 3,

    VARIABLE_BOOL_TYPE = 0 | 0x80,
    VARIABLE_INT_TYPE = 1 | 0x80,
    VARIABLE_DOUBLE_TYPE = 2 | 0x80,
    VARIABLE_STRING_TYPE = 3 | 0x80
};

struct Function
{
    std::string                                 fname;
    std::vector&lt;int&gt;                            indexes;
    std::function&lt;variable(variableList &amp;&amp;)&gt;    fn;

    variable operator()(variableList &amp;&amp; list)
    {
        if (indexes.size() != list.size() &amp;&amp;
            (indexes.size() == 0 || (indexes[0] &amp; 0x80) != 0x80))
        {
            std::cout &lt;&lt; "Invalid number of arguments" &lt;&lt; std::endl;
            return variable(0);
        }


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

        return fn(std::forward&lt;decltype(list)&gt;(list));
    }
};

int main()
{
    Function f = { "fName", {BOOL_TYPE, INT_TYPE, BOOL_TYPE}, [](variableList &amp;&amp; list) -&gt; variable {
        for (auto i : list)
        {
            std::visit([](auto &amp;&amp; val) -&gt; void {
                std::cout &lt;&lt; val &lt;&lt; std::endl;
            }, i);
        }
        return variable(0);
    }};

    auto arguments = {variable(true),variable(true),variable(true)};
    auto returnValue = f(arguments);
}


The project supports c++17. Any modifications, suggestions are welcome.

EDIT: Initially I wanted to use templates instead of indices and enum, but I wasn't quite successful with creating array of Function class with different template arguments.
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.