容器模板参数的 value_type [英] Value_type of a container template parameter

查看:29
本文介绍了容器模板参数的 value_type的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在他今年 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::beginstd::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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆