有没有办法构造vector
作为2 vector
s的连接(除了创建辅助函数?)
例如:
const vector<int> first = {13};
const vector<int> second = {42};
const vector<int> concatenation = first + second;
我知道vector
没有有string
这样的加法运算符,但这就是我想要的行为。这样concatenation
将包含:13和42。
我知道我可以像这样初始化concatenation
,但它阻止我制作concatenation
const
:
vector<int> concatenation = first;
first.insert(concatenation.end(), second.cbegin(), second.cend());
答案 0 :(得分:5)
不,如果您需要
,则无法实现const
。答案 1 :(得分:1)
我认为你必须写一个帮助功能。我把它写成:
std::vector<int> concatenate(const std::vector<int>& lhs, const std::vector<int>& rhs)
{
auto result = lhs;
std::copy( rhs.begin(), rhs.end(), std::back_inserter(result) );
return result;
}
将其称为:
const auto concatenation = concatenate(first, second);
如果向量可能非常大(或包含复制成本昂贵的元素),那么您可能需要先执行reserve
来保存重新分配:
std::vector<int> concatenate(const std::vector<int>& lhs, const std::vector<int>& rhs)
{
std::vector<int> result;
result.reserve( lhs.size() + rhs.size() );
std::copy( lhs.begin(), lhs.end(), std::back_inserter(result) );
std::copy( rhs.begin(), rhs.end(), std::back_inserter(result) );
return result;
}
(就个人而言,如果有证据证明这是瓶颈,我只会烦恼。)
答案 2 :(得分:1)
template<typename T>
std::vector<T> operator+(const std::vector<T>& v1, const std::vector<T>& v2){
std::vector<T> vr(std::begin(v1), std::end(v1));
vr.insert(std::end(vr), std::begin(v2), std::end(v2));
return vr;
}
这确实需要辅助“功能”,但至少它允许你将其用作
const vector<int> concatenation = first + second;
答案 3 :(得分:0)
class Vector : public vector<int>
{
public:
Vector operator+(const Vector& vec);
};
Vector Vector::operator+(const Vector& vec)
{
for (int i = 0; i < vec.size(); i++)
{
this->push_back(vec[i]);
}
return *this;
}
答案 4 :(得分:0)
让我先说这是一个黑客,并且不使用vector
给出如何做到这一点的答案。相反,我们将依赖sizeof(int) == sizeof(char32_t)
并使用u32string
来包含我们的数据。
This answer非常清楚仅原语可以在basic_string
中使用,并且任何大于32位的原语都需要编写自定义{{1}但是对于char_traits
,我们可以使用int
。
可以通过以下方式验证此资格:
u32string
一旦确定了大小平等,并且知道不能使用非static_assert(sizeof(int) == sizeof(char32_t));
const
,data
或emplace
之类的内容,{{1} }可以像emplace_back
一样使用,其中包括一个附加的操作符:
u32string
答案 5 :(得分:0)
我遇到了这个问题,正在寻找相同的东西,希望有比我想出的方法更简单的方法……似乎没有。
因此,如果您不介意帮助程序模板类,则应该使用一些迭代器技巧:
#include <vector>
#include <iostream>
template<class T>
class concat
{
public:
using value_type = typename std::vector<T>::const_iterator::value_type;
using difference_type = typename std::vector<T>::const_iterator::difference_type;
using reference = typename std::vector<T>::const_iterator::reference;
using pointer = typename std::vector<T>::const_iterator::pointer;
using iterator_category = std::forward_iterator_tag;
concat(
const std::vector<T>& first,
const std::vector<T>& last,
const typename std::vector<T>::const_iterator& iterator) :
mFirst{first},
mLast{last},
mIterator{iterator}{}
bool operator!= ( const concat& i ) const
{
return mIterator != i.mIterator;
}
concat& operator++()
{
++mIterator;
if(mIterator==mFirst.end())
{
mIterator = mLast.begin();
}
return *this;
}
reference operator*() const
{
return *mIterator;
}
private:
const std::vector<T>& mFirst;
const std::vector<T>& mLast;
typename std::vector<T>::const_iterator mIterator;
};
int main()
{
const std::vector<int> first{0,1,2,3,4};
const std::vector<int> last{5,6,7,8,9};
const std::vector<int> concatenated(
concat<int>(first,last,first.begin()),
concat<int>(first,last,last.end()));
for(auto i: concatenated)
{
std::cout << i << std::endl;
}
return 0;
}
您可能必须实现operator ++(int)或operator ==,具体取决于您的STL实现InputIterator构造函数的方式,这是我为MingW GCC可以想到的最小迭代器代码示例。
玩得开心! :)