如何在一行c ++中递增对值的同时初始化对的向量

时间:2016-06-27 10:17:35

标签: c++ stl

我想使用STL在一行中初始化pair<char, int>的向量。 从我发现以下的工作,但只能初始化具有相同值的每个元素。

vector<pair<char, int>> myVec (26, std::make_pair('a', -1));

有没有办法初始化它,可能使用lamda函数或其他东西,以便char元素将是增量的,如:

(a,-1) (b,-1) (c,-1) etc...

并且所有这些都在一行中而不是在初始化后使用经典循环? 提前谢谢。

6 个答案:

答案 0 :(得分:5)

如果不使用某种样板或外部依赖(例如,提升,请参阅其他答案),这是不可能的(作为单行)

使用std::generate的双线:

std::vector<std::pair<char, int>> v(26);
std::generate(v.begin(), v.end(), [] { static char c = 'a'; return std::make_pair(c++, -1);} );

答案 1 :(得分:2)

这不是一行,但这里的方法相当于在没有循环的情况下调用push_back

vector<pair<char,int>> v;
generate_n(
    back_insert_iterator<std::vector<pair<char,int>>>(v)
,   26
,   [c = 'a']() mutable { return make_pair(c++, -1); }
);

Demo.

答案 2 :(得分:1)

或者您可以使用std::generatestd::generate_n

或者手写的基于范围的for循环 - 我个人更喜欢这种方法。

或者您可以将BOOST_PP_ENUM用作:

#include <iostream>
#include <boost/preprocessor/repetition/enum.hpp>

#define PAIR(count, i, data) std::make_pair('a' + i, -1)

int main() 
{
  std::vector<std::pair<char, int>> vec { BOOST_PP_ENUM(26, PAIR, ~) };
}

该行:

std::vector<std::pair<char, int>> vec { BOOST_PP_ENUM(26, PAIR, ~) };

扩展到:

std::vector<std::pair<char, int>> vec {
      std::make_pair('a' + 0, -1),
      std::make_pair('a' + 1, -1),
      std::make_pair('a' + 2, -1),
      .
      .
      std::make_pair('a' + 25, -1)
};

答案 3 :(得分:0)

无论你如何削减它,你都必须定义“矢量生成”的含义。

最后,表达这一点的最简洁方法可能是将矢量生成封装在一个函数中,然后依靠RVO“做正确的事情”。

你会发现在调试时能够放置断点也很好。

#include <vector>
#include <utility>

using namespace std;

// define the concept of 'a generated vector'.
// I used a lambda but this could just as well be a free function
// or a function object
auto generate_vec = [] (std::size_t n, char first_char) {
  vector<pair<char, int>> myVec;
  myVec.reserve(n);
  while (n--) {
    myVec.emplace_back(first_char++, -1);
  }
  return myVec;
};

int main()
{
    // use the concept here
    vector<pair<char, int>> myVec  = generate_vec(26, 'a');
}

答案 4 :(得分:0)

写一次模板开销:

#include <utility>

// Make Sequence
// =============

namespace Detail {
    template <typename ResultSequence, typename IntegerSequence>
    struct make_sequence;

    template <typename ResultSequence, typename IndexType, IndexType...Indices>
    struct make_sequence<ResultSequence, std::integer_sequence<IndexType, Indices...>>
    {
        template <typename Callable, typename...Args>
        static constexpr ResultSequence apply(Callable&& fn, Args&&...args)
        {
            return { fn(Indices, std::forward<Args>(args)...) ... };
        }
    };
} // namespace Detail

template <typename ResultSequence, std::size_t N, typename Callable, typename...Args>
constexpr ResultSequence make_sequence(Callable&& fn, Args&&...args)
{
    return Detail::make_sequence<ResultSequence, std::make_index_sequence<N>>::apply(fn, args...);
}

// Test
// ====

#include <array>
#include <iostream>
#include <vector>
#include <map>
int main() {
    struct MissingConstexprLambda
    {
        constexpr std::pair<char, int> operator () (std::size_t i) {
            return std::make_pair(char('a' + i), -1);
        };
    };

    std::cout << "Array:\n";
    constexpr auto a = make_sequence<std::array<std::pair<char, int>, 3>, 3>(MissingConstexprLambda());
    for(const auto& p : a)
        std::cout << p.first << " = " << p.second << '\n';
    static_assert(std::get<1>(a).first == 'b', "");

    auto lambda = [](std::size_t i) { return std::make_pair('a' + i, -1); };

    std::cout << "Vector:\n";
    auto v = make_sequence<std::vector<std::pair<char, int>>, 3>(lambda);
    for(const auto& p : v)
        std::cout << p.first << " = " << p.second << '\n';

    std::cout << "Map:\n";
    auto m = make_sequence<std::map<char, int>, 3>(lambda);
    for(const auto& p : m)
        std::cout << p.first << " = " << p.second << '\n';
}

答案 5 :(得分:-1)

你可以做这样的事情:

hand

并创建这样的矢量:

class SomeClass
{
public:
    static char currentChar;
    SomeClass()
    {
        intValue = -1;
        charValue = currentChar;
        currentChar = static_cast<char>(currentChar + 1);
    }
    char charValue;
    int intValue;
};
char SomeClass::currentChar = *"a";

它将创建26个元素,从第一个到最后一个,每个默认构造函数将增加1个字母