Creating a vector or array of lambda functions

Question | Sep 24, 2019 | nextptr 

A lambda expression is a syntactic sugar on a function-object (an object with an overloaded function-call operator). There are some cases where we have to create a sequence collection (e.g., a vector or an array) of lambda expressions. One of those situations might arise when we have to build a pipeline of operations that need to be invoked in a sequence. In this question, let's assume that we have three operations, implemented as identical lambda expressions, that we want to store in an std::vector:

auto op1 = [](std::string& data) {
    // process data
    return true;
};

auto op2 = [](std::string& data) {
    // process data
    return true;
};

auto op3 = [](std::string& data) {
    // process data
    return true;
};

All lambda expressions have similar parameters and return types. We want to create an std::vector, vec, to store all the operations and invoke them in a for loop:

// Store all the operations
vec.push_back(op1);
vec.push_back(op2);
vec.push_back(op3);

// Somewhere else, invoke them in a loop
for(auto& op : vec)
    op(data); //'data' is std::string

Note that, all three lambda expressions have an empty capture clause, ([]), or they are not capturing anything from their outer scope. We have considered the following three possible types for the operations vector:

A) Vector of function objects:

std::vector<std::function<bool(std::string&)>> vec;

B) Vector of decltype of one of the lambda expressions:

std::vector<decltype(op1)> vec;

C) Vector of function pointers:

using FT = bool(std::string&); //function type alias of lambda operation
std::vector<FT*> vec; //vector of function pointers

Select below, all those types of vec from above that can store all the three operations (check Explanations for the details on the correct answer):