我想使用STL在一行中初始化pair<char, int>
的向量。
从我发现以下的工作,但只能初始化具有相同值的每个元素。
vector<pair<char, int>> myVec (26, std::make_pair('a', -1));
有没有办法初始化它,可能使用lamda函数或其他东西,以便char元素将是增量的,如:
(a,-1) (b,-1) (c,-1) etc...
并且所有这些都在一行中而不是在初始化后使用经典循环? 提前谢谢。
答案 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); }
);
答案 2 :(得分:1)
或者您可以使用std::generate
或std::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个字母