我可以在成员初始化列表中使用std :: minmax_element吗?

时间:2018-03-13 08:59:27

标签: c++ c++11

这是一个包含const std::vector的类,并存储其最小值和最大值:

#include <vector>
#include <algorithm>

class MyClass {

public:
    const std::vector<int> v;
    const std::pair<int, int> minmax_v;

    MyClass(const std::vector<int> & v_init)
    : v(v_init),
    minmax_v(*(std::min_element(v.begin(), v.end())), *(std::max_element(v.begin(), v.end()))) {}

};

有可能以某种方式使用std::minmax_element初始化minmax_v?我们的想法是提高绩效。

当然,可以在构造函数体中使用std::minmax_element并删除const的{​​{1}},但这也感觉不对。

2 个答案:

答案 0 :(得分:6)

使用委托构造函数在单个参数中获取class MyClass { public: const std::vector<int> v; const std::pair<int, int> minmax_v; MyClass(const std::vector<int> & v_init) : MyClass(v_init, std::minmax_element(v_init.begin(), v_init.end())) {} private: MyClass(const std::vector<int> & v_init, std::pair<std::vector<int>::const_iterator, std::vector<int>::const_iterator> p) : v(v_init), minmax_v(*p.first, *p.second) {} }; 个结果对:

String haveUeverSeenLorem = `Lorem ipsum dolor sit amet, 
consectetur adipisicing elit, 
sed do eiusmod tempor incididunt 
ut labore et dolore magna aliqua.`;

答案 1 :(得分:1)

由于您要求提高性能,我想指出在这种情况下使用自定义循环可能会更快。在您的示例中,有两个操作都迭代向量:vstd::minmax_element的初始化都遍历输入向量。迭代两次似乎不是最优的,因此将操作合并为一个循环可能更好。

class MyClass {
private:
    MyClass(std::tuple<int, int, std::vector<int>>&& x): v( std::get<2>(x) ), minmax_v( std::get<0>(x), std::get<1>(x)) {

}

    static std::tuple<int, int, std::vector<int>> init(std::vector<int> const& v_init) {
        std::vector<int> v;
        v.reserve(v_init.size());
        int min = v_init.front();
        int max = v_init.front();
        for(auto const& x: v_init) {
            v.push_back(x);

            if (min > x) {
                min = x;
            }

            if (max < x) {
                max = x;
            }
        }

        return std::make_tuple(min,max, std::move(v));
    }

public:
    const std::vector<int> v;
    const std::pair<int, int> minmax_v;

    MyClass(const std::vector<int> & v_init): MyClass(init(v_init)) {}
};

我假设输入向量不为空,因为原始示例也取消引用结果std::min_elementstd::max_element而不对v_init.end()进行检查。由于const成员无法在构造函数体中初始化,因此我不得不使用辅助元组来解决问题。

我还想说我可能更喜欢使用STL算法而不是手写循环,直到我看到性能问题。 Modern compilers probably merge the two loop into a single loop and produce efficient code.