Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在一行c+中递增对值的同时初始化对向量+;_C++_Stl - Fatal编程技术网

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

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

我想使用STL在一行中初始化
对的向量。
从我发现的情况来看,以下方法可以工作,但只能用相同的值初始化每个元素

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不幸的是,没有,