lundi 29 août 2022

const reference to temporary variable does not work for std::function whose type does not match its declaration

class Context {
public:
    Context(){
        field2values_["age"] = std::vector<int>{1,2,3};
    }

    const std::vector<int>& field2values(const std::string& field) const {
        auto it = field2values_.find(field);
        if (it == field2values_.end()) {
            return default_ints_;
        }
        return it->second;
    }

private:
    std::map<std::string, std::vector<int>> field2values_;
    std::vector<int> default_ints_;
};

Context ctx;

std::vector<int> ctx_field2values(const std::string& field) {
    return ctx.field2values(field);
}

class Checker {
public:
    explicit Checker():
            user_field_values_(ctx_field2values),
            user_field_values_nc_(ctx_field2values)
    {}

    void print(){
        const auto& values = user_field_values_("age");
        std::cout << "size=" << values.size() << std::endl;  // unexpected: 18446744073709535740
        const auto& values_nc = user_field_values_nc_("age");
        std::cout << "size=" << values_nc.size() << std::endl;  // expected: 3
    }

private:
    const std::function<const std::vector<int>&(const std::string&)> user_field_values_;
    const std::function<std::vector<int>(const std::string&)> user_field_values_nc_;
};

int main() {
    Checker checker;
    checker.print();
}

As we all know, const reference to temporary variable will extend the its lifetime. But in the code above, it does not work for user_field_values_ while it works for user_field_values_nc_. I guess this is because the type of user_field_values_ does not match its initialization, namely ctx_field2values. But why is there such a difference? Can anyone explain in principle why this rule (const reference to temporary variable) does not take effect? Thanks in advance.

Aucun commentaire:

Enregistrer un commentaire