[英]std::vector< MyObj* > to std::vector< MyObj Const * >, how to no loops?
Title, 标题,
Let say we have 让我们说
std::vector<MyObj*> ArrayOfPtr;
std::vector<MyObj const *> ArrayOfPtrToConstObj;
int main()
{
//I'd like to give ArrayOfPtr to another obj/function but not give it the right to modify the objects in it.
ArrayOfPtrToConstObj = ArrayOfPtr;
Function(ArrayOfPtrToConstObj)
}
Why can't that be written in C++ and understood automatically by the compiler considering const does not alter the logic (optimization or anything)..? 为什么不能用C ++编写并且编译器自动理解,考虑到const不会改变逻辑(优化或任何东西)..?
Is there a quick way to go from vector 1 to vector 2 without having to for/while loop onto the array and fill the second one? 有没有一个快速的方法从矢量1到矢量2而不必for / while循环到阵列上并填充第二个?
Well, someone, somewhere is going to have to loop. 好吧,有人,某个地方将不得不循环。 You can avoid writing the loop yourself by using
vector::assign
: 您可以使用
vector::assign
避免自己编写循环:
ArrayOfPtrToConstObj.assign(ArrayOfPtr.begin(), ArrayOfPtr.end());
But assign
is still going to loop. 但
assign
仍然会循环。
The preferred modern solution is to either pass an const-iterator/pointer pair and let the user consume them, or to use a view class like gsl::span
. 首选的现代解决方案是传递一个const-iterator / pointer对,让用户使用它们,或者使用像
gsl::span
这样的视图类。 This requires no copying of anything, and can add const
as needed: 这不需要复制任何东西,并且可以根据需要添加
const
:
gsl::span<MyObj const*> spn(ArrayOfPtr.data(), ArrayOfPtr.size());
vector2
is a fundamentally different type. vector2
是一种根本不同的类型。 If, however, you just want to view the inside of vector1
in a const
manner, I have a solution for you. 但是,如果您只想以
const
方式查看vector1
的内部,我可以为您提供解决方案。
I'd start with something like, but not exactly, gsl::span
. 我会从像
gsl::span
这样的东西开始。
template<class T>
struct span {
private:
T* b = 0;
T* e = 0;
public:
T* begin() const { return b; }
T* end() const { return e; }
T* data() const { return begin(); }
template<class U>
using compatible = std::enable_if_t< std::is_convertible< U*, T* >{} && sizeof(T)==sizeof(U), bool >;
template<class U,
compatible<U> =true
>
span( U* s, U* f ): b(s), e(f) {}
template<class U,
std::enable_if_t< std::is_convertible< U*, T* >{} && sizeof(T)==sizeof(U), bool > =true
>
span( U* s, std::size_t length ): span( s, s+length ) {}
// pointer semantics:
span()=default;
span(span const&)=default;
span& operator=(span const&)=default;
~span()=default;
std::size_t size() const{ return end()-begin(); }
bool empty() const{ return end()==begin(); }
T& front() const { return *begin(); }
T& back() const { return *(end()-1); }
// sub spans:
span without_front( std::size_t n=1 ) const {
n = (std::min)(n, size());
return {begin()+n, end()};
}
span without_back( std::size_t n=1 ) const {
n = (std::min)(n, size());
return {begin(), end()-n};
}
span only_front( std::size_t n=1 ) const {
n = (std::min)(n, size());
return {begin(), begin()+n};
}
span only_back( std::size_t n=1 ) const {
n = (std::min)(n, size());
return {end()-n, end()};
}
span sub( std::size_t start, std::size_t length ) const {
return without_front(start).only_front(length);
}
T& operator[](std::size_t I)const{ return begin()[I]; }
T& at(std::size_t I)const{
if (I>=size()) throw std::out_of_range{"index"};
return begin()[I];
}
std::vector<std::decay_t<T>> as_vector()const& {
return {begin(), end()};
}
std::vector<std::decay_t<T>> as_vector()&& {
return {std::make_move_iterator(begin()), std::make_move_iterator(end())};
}
template<class C,
compatible< std::decay_t< decltype( *std::declval<C&>().data() ) > > =true,
std::enable_if_t< !std::is_same<span, std::decay_t<C>>{}, bool > =true
>
span( C&& c ): span(c.data(), c.size()) {}
};
If you do not intend to change the length of a vector
in a context, a span
is the right answer. 如果您不打算在上下文中更改
vector
的长度,则span
是正确的答案。
Live example with some tests. 一些测试的实例 。
Function
in this case should take span< MyObj const*const >
, stating it just wants to look at a buffer of MyObj const
s. 在这种情况下的
Function
应该采用span< MyObj const*const >
,声明它只是想查看MyObj const
的缓冲区。 You can store a span of this type if you want to, or let implicit conversion work: 如果您愿意,可以存储此类型的范围,或者让隐式转换工作:
std::vector<MyObj*> ArrayOfPtr;
span<MyObj const*const> SpanOfPtrToConstObj;
int main()
{
//I'd like to give ArrayOfPtr to another obj/function but not give it the right to modify the objects in it.
SpanOfPtrToConstObj = ArrayOfPtr;
Function(SpanOfPtrToConstObj)
}
Function
cannot modify the length of the vector or the pointers within it or what the pointers point to. Function
不能修改向量的长度或其中的指针或指针指向的长度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.