C++ 如何在一行c+中递增对值的同时初始化对向量+;
我想使用STL在一行中初始化C++ 如何在一行c+中递增对值的同时初始化对向量+;,c++,stl,C++,Stl,我想使用STL在一行中初始化对的向量。 从我发现的情况来看,以下方法可以工作,但只能用相同的值初始化每个元素 vector<pair<char, int>> myVec (26, std::make_pair('a', -1)); 所有这些都在一行中,而不在初始化后使用经典循环? 提前感谢。或者您可以使用std::generate或std::generate\n 或者手写基于范围的循环-我个人更喜欢这种方法 或者您可以使用BOOST\u PP\u ENUM作为: #i
对的向量。
从我发现的情况来看,以下方法可以工作,但只能用相同的值初始化每个元素
vector<pair<char, int>> myVec (26, std::make_pair('a', -1));
所有这些都在一行中,而不在初始化后使用经典循环?
提前感谢。或者您可以使用std::generate
或std::generate\n
或者手写基于范围的循环-我个人更喜欢这种方法
或者您可以使用BOOST\u PP\u 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, ~) };
}
#包括
#包括
#定义对(计数、i、数据)std::make_PAIR('a'+i,-1)
int main()
{
向量向量{BOOST_PP_ENUM(26,对,~)};
}
该行:
std::vector<std::pair<char, int>> vec { BOOST_PP_ENUM(26, PAIR, ~) };
std::向量向量{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)
};
标准:向量向量向量{
标准::组成配对('a'+0,-1),
标准::组成配对('a'+1,-1),
标准::制造成对('a'+2,-1),
.
.
标准::配对('a'+25,-1)
};
如果不使用某种样板文件或外部依赖(例如boost,请参阅其他答案),这是不可能的(作为一个线性程序)
使用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);} );
std::vectorv(26);
std::generate(v.begin(),v.end(),[]{static char c='a';返回std::make_pair(c++,-1);});
无论您以何种方式切割,都必须定义“向量生成”的概念
最后,可能最简洁的表达方式是将向量生成封装在函数中,然后依靠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');
}
#包括
#包括
使用名称空间std;
//定义“生成向量”的概念。
//我使用了lambda,但这也可以是一个自由函数
//或函数对象
自动生成向量=[](标准::大小\u t n,字符优先\u字符){
载体myVec;
myVec储备(n);
而(n--){
myVec.emplace_back(第一个字符++,-1);
}
返回myVec;
};
int main()
{
//在这里使用这个概念
向量myVec=生成向量(26,'a');
}
您可以制作如下内容:
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";
std::vector<SomeClass> v(26);
class-SomeClass
{
公众:
静态字符-当前字符;
SomeClass()
{
intValue=-1;
charValue=currentChar;
currentChar=静态_转换(currentChar+1);
}
char值;
int值;
};
char SomeClass::currentChar=*“a”;
创建如下向量:
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";
std::vector<SomeClass> v(26);
std::vectorv(26);
它将从头到尾创建26个元素,每个默认构造函数将字母增加1这不是一行,但这里有一种方法相当于调用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); }
);
向量v;
生成(
反向插入迭代器(v)
, 26
,[c='a']()可变{return make_pair(c++,-1);}
);
一些模板开销只写一次:
#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';
}
#包括
//制作序列
// =============
名称空间详细信息{
样板
构造make_序列;
样板
结构生成序列
{
样板
静态constexpr ResultSequence apply(可调用&&fn、Args&&…Args)
{
返回{fn(索引,std::forward(args)…)};
}
};
}//名称空间详细信息
样板
constexpr ResultSequence make_序列(可调用的&&fn、Args&&…Args)
{
返回详细信息::make_sequence::apply(fn,args…);
}
//试验
// ====
#包括
#包括
#包括
#包括
int main(){
结构缺失consteprlambda
{
constexpr std::pair运算符()(std::size\u t i){
返回std::make_对(char('a'+i),-1);
};
};
std::如果std::vector
构造函数不支持这一点,请使用类似于std::iota
的方法看看这个问题:特别是前两个答案。它们可能会帮助您完成您想做的事情!不是没有一些样板或相当复杂的lambda。您希望每对中的第一个都是一个le吗tter?我问的原因是,现实世界中存在字母a-z不连续的字符集(例如,a
和z
之间的字符不是字母)@RichardHodges我真的很想看到这个解决方案,只是出于教育目的。有人可能会问,如果我们要建立一些宏样板,为什么不建立一些代码样板呢?我个人更喜欢手写基于范围的for
循环。我不确定我是否喜欢这个建议。宏通常比编写c更不安全ode。此外,OP似乎在寻找依赖STL的东西,而引用boost会增加一个依赖项。虽然我们不知道OP对依赖项的看法,但仅仅为了实现这一点,链接boost似乎有些过分。使用循环会更合适,IMHO。@ray:我同意。有很多方法可以填充数组。至于是哪种方法st取决于实际场景。OP要求一个简单的解决方案,理想情况下是一个单行程序。您提出了一个完整的类。我认为这与所请求的内容相差太远,并且具有其他不必要的含义。例如,该类并不真正表示对象,它只是试图完成函数的工作。。。在一个ctor中…它无缘无故地污染了名称空间,使用了更多的资源,等等。糟糕的代码似乎是一个错误overkill@Polikdir有点冗长,一次也不能用,但没有过度使用我想知道在C++14中,[C='A'](){..}
是否有效?@Nawaz不幸的是,没有,