容器模板参数的 value_type [英] Value_type of a container template parameter
问题描述
在他今年 Going Native 的主题演讲中 C++ 的本质(转至 40:30)Bjarne Stroustrup 给出了以下代码示例:
In his keynote of this years Going Native The Essence of C++ (go to 40:30) Bjarne Stroustrup gives the following code example:
template<typename C, typename V>
vector<Value_type<C>*> find_all(C& cont, V v)
{
vector<Value_type<C>*> res;
for (auto& x : cont)
if (x == v)
res.push_back(&x)
return res;
}
此函数用于查找容器中所有出现的值并返回指向找到的元素的指针.视频中的例子:
This function is used to find all occurrences of a value in a container and returns pointers to the found elements. The example from the video:
string m{"Mary had a little lamb"};
for (const auto p: find_all(m,'a')) // p is a char*
if (*p != 'a')
cerr << "string bug!\n";
我的问题是关于 Value_Type
.标准中有没有这样的东西图书馆?我寻找它并没有找到它.如果它不在标准中,如何实现?
My question is about Value_Type<C>*
. Is there something like this in the standard
library? I looked for it and didn't find it. How could this be implemented, if it's not in std?
推荐答案
我不知道标准中有这个,但实现起来并不难:
I don't know of this in the standard, but it's not hard to implement:
template <class C>
struct value_type
{
typedef typename C::value_type type;
};
template <class T, int N>
struct value_type<T[N]>
{
typedef T type;
};
template <class T>
struct value_type<T*>
{
typedef T type;
};
现在您可以使用 typename value_type<C>::type
来访问容器包含的类型.如果您有自己想要使用的容器,但它没有 value_type
typedef(无论出于何种原因,您都无法更改它),那么您可以简单地为该容器专门化这个结构体嗯.
and now you can use typename value_type<C>::type
to access the type that a container contains. If you have your own container you would like to use but it doesn't have a value_type
typedef (and for whatever reason you can't change it) then you can simply specialize this struct for that container as well.
为了避免 typename ...::type
你可以这样做:
To avoid the typename ...::type
you can do:
template <class C>
using Value_Type = typedef value_type<C>::type;
现在您只需在任何地方使用 Value_Type
.
and now you just use Value_Type<C>
everywhere.
编辑
正如 stefan 在很快的回答中建议的那样,您可以使用 std::begin
更轻松地做到这一点,这是可以的,因为您使用/创建的任何容器都希望能够调用 std::begin
和 std::end
无论如何:
EDIT
As stefan suggested in soon's answer, you can do this more easily with std::begin
which is okay because any container you use/create you would want to be able to call std::begin
and std::end
on anyway:
template <class C>
using Value_Type = typename std::remove_reference<
decltype(*std::begin(std::declval<
typename std::add_lvalue_reference<C>::type>()))>::type;
这更简洁,但读起来有点密集.它仍然比第一个选项好,这将需要更少的自定义容器类型的样板代码.
This is much more concise, though it's gotten a little dense to read. It's still better than the first option, this will require less boilerplate code for custom container types.
这篇关于容器模板参数的 value_type的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!