c++vectorstd-variant

Is there an option to create a vector that contains functions with different return types?


I have the following vectors

std::vector<std::pair<std::string, std::function<std::string(const PlayerFRDb&)>>> stringExtractors = {
    {" TEAM ", extractTeam},
    {" NAME ", extractName},
    {" TYPE ", extractProperty4},
};

std::vector<std::pair<std::string, std::function<int(const PlayerFRDb&)>>> intExtractors = {
    {" WS ", extractProperty0},
    {" LS ", extractProperty1},
    {" W ", extractProperty2},
    {" L ", extractProperty3},
};

std::vector<std::pair<std::string, std::function<char(const PlayerFRDb&)>>> charExtractors = {
    {" WAY ", extractProperty5},
};

std::vector<std::pair<std::string, std::function<double(const PlayerFRDb&)>>> doubleExtractors = {
    {" LINE ", extractProperty6},
};

To make it easier to work with these functions, I want to lump them into one vector, but the problem is that they return different types.

I tried using std::variant, but I can't initialize the vector, because the compiler prints out: "no instance of constructor matches the argument list argument types are ({...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}) "

using FuncVariant = std::variant<
    std::function<std::string(const PlayerFRDb&)>,
    std::function<int(const PlayerFRDb&)>,
    std::function<double(const PlayerFRDb&)>
>;

std::vector<std::pair<std::string, FuncVariant>> extractors = {
    {" TEAM ", extractTeam},
    {" NAME ", extractName},
    {" TYPE ", extractProperty4},
    {" WS ", extractProperty0},
    {" LS ", extractProperty1},
    {" W ", extractProperty2},
    {" L ", extractProperty3},
    {" LINE ", extractProperty6},
};

Is there an option to create a vector that contains functions with different return types?


Solution

  • to help the compiler deduce the template arguments you can wrap all functions with std::function{}.

    #include <variant>
    #include <functional>
    #include <string>
    
    int foo(void) {return 0;}
    char bar(void) {return '0';}
    
    using FuncVariant = std::variant<std::function<int()>,std::function<char()>>;
    int main()
    {
        std::vector<std::pair<std::string, FuncVariant>> vec{
            {"TEAM", std::function{bar}},
            {"W", std::function{foo}}
        };
        return 0;
    }