V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
linux40
V2EX  ›  C

一个关于 c++的初始化列表( 17 行)问题?

  •  
  •   linux40 · May 6, 2015 · 1468 views
    This topic created in 4021 days ago, the information mentioned may be changed or developed.

    ifndef STRBLOB_H

    define STRBLOB_H

    include <string>

    include <memory>

    include <vector>

    include <exception>

    include <initializer_list>

    class StrBlobPtr;
    class const_StrBlobPtr;
    class StrBlob
    {
    friend class StrBlobPtr;
    friend class const_StrBlobPtr;
    public:
    typedef std::vector<std::string>::size_type size_type;
    StrBlob(std::initializer_list<std::string> il)://这里为什么不能是引用?
    data(std::make_shared<std::vector<std::string>>(il)) {}
    StrBlob(): data(std::make_shared<std::vector<std::string>>()) {}

    std::string &front()
    {
        check(0, "front on empty StrBlob");
        return data->front();
    }
    const std::string &front() const
    {
        check(0, "front on empty StrBlob");
        return data->front();
    }
    std::string &back()
    {
        check(0, "back on empty StrBlob");
        return data->back();
    }
    const std::string &back() const
    {
        check(0, "back on empty StrBlob");
        return data->back();
    }
    size_type size() const { return data->size(); }
    bool empty() const { return data->empty(); }
    void push_back(const std::string &s) { data->push_back(s); }
    void pop_back() { data->pop_back(); }
    StrBlobPtr begin();
    StrBlobPtr end();
    const_StrBlobPtr begin() const;
    const_StrBlobPtr end() const;
    const_StrBlobPtr cbegin() const;
    const_StrBlobPtr cend() const;
    

    private:
    std::shared_ptr<std::vector<std::string>> data;
    void check(size_type i, const std::string &msg) const
    { if (i >= size()) throw std::out_of_range(msg); }
    };

    class StrBlobPtr
    {
    public:
    StrBlobPtr(StrBlob &sb, StrBlob::size_type sz = 0):
    wptr(sb.data), curr(sz) {}
    StrBlobPtr(): curr(0) {}

    std::string &deref() const
    {
        return (*check(curr, "dereference past end"))[curr];
    }
    StrBlobPtr &incr()
    {
        check(curr, "increment past end of StrBoldPtr");
        ++curr;
        return *this;
    }
    bool compare(const StrBlobPtr &sp)
        {return (wptr.lock() == sp.wptr.lock())&&(curr == sp.curr); }
    

    private:
    std::shared_ptr<std::vector<std::string>>
    check(StrBlob::size_type pos, const std::string &msg) const
    {
    auto ret = wptr.lock();
    if (!ret)
    throw std::runtime_error("unbound StrBlobPtr");
    if (pos >= ret->size())
    throw std::out_of_range(msg);
    return ret;
    }
    std::weak_ptr<std::vector<std::string>> wptr;
    StrBlob::size_type curr;
    };

    class const_StrBlobPtr
    {
    public:
    const_StrBlobPtr(const StrBlob &sb, StrBlob::size_type sz = 0):
    wptr(sb.data), curr(sz) {}
    const_StrBlobPtr(): curr(0) {}

    const std::string &deref() const
    {
        return (*check(curr, "dereference past end"))[curr];
    }
    const_StrBlobPtr &incr()
    {
        check(curr, "increment past end of StrBoldPtr");
        ++curr;
        return *this;
    }
    bool compare(const const_StrBlobPtr &sp) const
        {return (wptr.lock() == sp.wptr.lock())&&(curr == sp.curr); }
    

    private:
    std::shared_ptr<const std::vector<std::string>>
    check(StrBlob::size_type pos, const std::string &msg) const
    {
    auto ret = wptr.lock();
    if (!ret)
    throw std::runtime_error("unbound StrBlobPtr");
    if (pos >= ret->size())
    throw std::out_of_range(msg);
    return ret;
    }
    std::weak_ptr<const std::vector<std::string>> wptr;
    StrBlob::size_type curr;
    };

    inline StrBlobPtr StrBlob::begin() { return StrBlobPtr(*this); }
    inline StrBlobPtr StrBlob::end() { return StrBlobPtr(*this, size()); }
    inline const_StrBlobPtr StrBlob::begin() const
    { return const_StrBlobPtr(*this); }

    inline const_StrBlobPtr StrBlob::end() const
    { return const_StrBlobPtr(*this, size()); }

    inline const_StrBlobPtr StrBlob::cbegin() const
    { return const_StrBlobPtr(*this); }

    inline const_StrBlobPtr StrBlob::cend() const
    { return const_StrBlobPtr(*this, size()); }

    endif // STRBLOB_H

    /×顺便大家吐槽一下有没有什么改进的地方,其实就是cpp_primer的练习12.22,格式好像有点乱啊,不想看别看了。。。×/

    Supplement 1  ·  May 6, 2015
    UPDATE:https://gist.github.com/c3a14f6c8b10a83ece3c.git
    Supplement 2  ·  May 6, 2015
    17行那里为什么不能是引用?
    Supplement 3  ·  May 6, 2015
    6 replies    2015-05-07 09:08:43 +08:00
    sablib
        1
    sablib  
       May 6, 2015
    = = 代码被当成 markdown了。。
    linux40
        2
    linux40  
    OP
       May 6, 2015
    @sablib 只有默认和markdown啊。。。
    我是直接托的代码啊。。。
    sablib
        3
    sablib  
       May 6, 2015
    @linux40 可以用gist
    linux40
        4
    linux40  
    OP
       May 6, 2015
    @sablib 3q
    comicfans44
        5
    comicfans44  
       May 7, 2015
    根据http://en.cppreference.com/w/cpp/utility/initializer_list的说明
    since c++14:
    The underlying array is a temporary array, in which each element is copy-initialized (except that narrowing conversions are invalid) from the corresponding element of the original initializer list. The lifetime of the underlying array is the same as any other temporary object, except that initializing an initializer_list object from the array extends the lifetime of the array exactly like binding a reference to a temporary (with the same exceptions, such as for initializing a non-static class member). The underlying array may be allocated in read-only memory.

    因为是临时对象,所以不能用引用。

    但const 引用是可以的,与传值效果相同,因为initializer_list的拷贝不会进行内部元素的拷贝,这一点可参考c++标准18.9
    An object of type initializer_list<E> provides access to an array of objects of type const E. [ Note:
    A pair of pointers or a pointer plus a length would be obvious representations for initializer_list.
    initializer_list is used to implement initializer lists as specified in 8.5.4. Copying an initializer list does
    not copy the underlying elements. — end note ]
    linux40
        6
    linux40  
    OP
       May 7, 2015
    @comicfans44 谢谢,知道了。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3021 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 08:27 · PVG 16:27 · LAX 01:27 · JFK 04:27
    ♥ Do have faith in what you're doing.