如何初始化 'const std::vector' 像交流阵列
是否有一种优雅的方法来创建和初始化一个 const std::vector
,例如 const T a[] = { ... }
为固定值(并且小)值的数量?
我需要经常调用一个需要 vector
的函数,但在我的情况下这些值永远不会改变。
原则上我想到了类似的东西,
namespace {
const std::vector<const T> v(??);
}
因为 v 不会在这个编译单元之外使用。
Is there an elegant way to create and initialize a const std::vector<const T>
like const T a[] = { ... }
to a fixed (and small) number of values?
I need to call a function frequently which expects a vector<T>
, but these values will never change in my case.
In principle I thought of something like
namespace {
const std::vector<const T> v(??);
}
since v won't be used outside of this compilation unit.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
对于 C++11:
原始答案:
您要么必须等待 C++0x,要么使用类似 Boost.Assign 来做到这一点。
例如:
For C++11:
Original answer:
You would either have to wait for C++0x or use something like Boost.Assign to do that.
e.g.:
如果您询问如何初始化 const 向量以使其具有有趣的内容,那么答案可能是使用复制构造函数。 首先,您需要费力地填充一个向量,然后从中创建新的常量向量。 或者,您可以使用
vector(InputIterator, InputIterator)
构造函数模板从其他类型的容器或数组进行初始化。 如果是数组,则可以使用初始化列表来定义它。像这样的东西希望接近你想要的:
如果你问如何将 const 向量传递到接受向量的函数中,那么答案是:
或者
后者是其中之一,很正确地,任何看到它的人都会对护目镜发表评论,而且事实上它们什么也没做。 这正是 const_cast 的用途,但有一个相当有力的论据表明,如果您需要 const_cast ,那么您就已经失败了。
做这两件事(使用复制构造函数从非常量向量创建一个常量向量,然后抛弃常量性)绝对是错误的 - 你应该只使用一个非常量向量。 因此,最多选择其中一项来执行...
[编辑:刚刚注意到您正在谈论
vector
和const vector< 之间的区别;const T>
。 不幸的是,在 STL 中,vector
和vector
是完全不相关的类型,它们之间转换的唯一方法是通过复制。 这是向量和数组之间的区别 -T**
可以静默且安全地转换为const T *const *
]If you're asking how to initialise a const vector so that it has interesting contents, then the answer is probably to use the copy constructor. First you laboriously fill in a vector, then you create your new const vector from it. Or you can use the
vector<InputIterator>(InputIterator, InputIterator)
constructor template to initialise from some other kind of container or an array. If an array, then that could have been defined with an initialisation list.Something like this is hopefully close to what you want:
If you're asking how to pass a const vector into a function which takes a vector then the answer is either:
or
const_cast
to remove the constness in order to pass it into a function which takes a non-const vector but which you just so happen to know will not modify the vector.The latter is one of those things which will, quite rightly, cause anyone who sees it to make comments about goggles, and the fact that they do nothing. It's exactly what
const_cast
is for, but there's a reasonably strong argument that says if you needconst_cast
, you have already lost.Doing both of those things (creating a const vector from a non-const one with the copy constructor, and then casting away constness) is definitely wrong - you should have just used a non-const vector. So pick at most one of these to do...
[Edit: just noticed that you're talking about a difference between
vector<T>
andconst vector<const T>
. Unfortunately in the STL,vector<const T>
andvector<T>
are completely unrelated types, and the only way to convert between them is by copying. This is a difference between vectors and arrays - aT**
can be silently and safely converted toconst T *const *
]简短而肮脏的方式(类似于 Boost 的
list_of()
)现在,C++11 具有初始化列表,因此您不需要那样做,甚至不需要使用 Boost。 但是,作为一个例子,您可以在 C++11 中更有效地执行上述操作,如下所示:
但是,它仍然不如使用 C++11 初始值设定项列表高效,因为没有
operator=(vlist_of&& )
为向量定义。tjohns20 的方式修改如下可能是更好的 c++11
vlist_of
:Short and dirty way (similar to Boost's
list_of()
)Now, C++11 has initializer lists, so you don't need to do it that way or even use Boost. But, as an example, you can do the above in C++11 more efficiently like this:
But, it's still not as efficient as using a C++11 initializer list because there's no
operator=(vlist_of&&)
defined for vector.tjohns20's way modified like the following might be a better c++11
vlist_of
:正如其他人所说,您不能像初始化 C 样式数组那样初始化向量,除非您为其提供指向源数组的指针。 但在这种情况下,如果您的向量是全局常量,为什么不直接使用旧的 C 样式数组呢?
您甚至可以对这个数组使用 STL 算法,就像对 const 向量使用算法一样......
As others have said, you can't init a vector the same way you can init a C-style array, unless you give it pointers to a source array. But in that case, if your vector is a global const, why not just use an old C-style array instead?
You can even use STL algorithms against this array, the same way you would use algorithms against a const vector...
您可以分两步完成:
也许不像您想要的那么漂亮,但很实用。
You can do it in two steps:
Perhaps not as beautiful as you might like, but functional.
怎么样:
How about:
老问题,但我今天遇到了同样的问题,这是最适合我的目的的方法:
避免过度复制的示例:
Old question, but I ran into the same issue today, here's the approach that was most acceptable for my purposes:
Example to avoid excessive copying:
如果它们都是相同的,你可以这样做
,但我假设它们不是 - 在这种情况下,最简洁的方法可能是:
C++0x 将让你以你想要的方式使用初始化列表,但是那是
不幸的是,现在没有太多好处。
If they're all the same you can just do
but I assume they're not - in which case the neatest way is probably:
C++0x will let you use an initialiser list in exactly the way you're thinking of, but that's
not a lot of good right now, unfortunately.
根据 Shadow2531 的响应,我使用此类来初始化向量,而不像 Shadow 的解决方案那样实际继承 std::vector
用法:
与 Steve Jessop 的解决方案相比,它创建了更多代码,但如果数组创建不具有性能关键我发现这是在一行中初始化数组的好方法
Based on Shadow2531's response, I'm using this class to initialise vectors, without actually inheriting from std::vector like Shadow's solution did
Usage:
Compared to Steve Jessop's solution it creates a lot more code, but if the array creation isn't performance critical I find it a nice way to initialise an array in a single line
不确定我是否理解正确。 我理解你的问题是这样的:你想将向量初始化为大量元素。 在向量上使用
push_back()
有什么问题吗? :-)如果您知道要存储的元素数量(或者确定它将存储小于 2 的下一个幂),则可以执行此操作,如果您有 X 类型的指针向量(仅适用于指针) :
即使使用
push_back()
,也要注意添加超过 2 的下一个幂的元素。 指向v.begin()
的指针将无效。Not sure if I understood you right. I understand your question like this: you want to initialize a vector to a large number of elements. What's wrong with using
push_back()
on the vector? :-)If you know the number of elements to be stored (or are sure that it will store less than the next power of 2) you can do this, if you have a vector of pointers of type X (works only with pointers):
Beware of adding more than the next power of 2 elements, even if using
push_back()
. Pointers tov.begin()
will then be invalid.