Boost logo

Boost :

Subject: [boost] [BOOST_FOREACH] Problem to iterate on a non-copyable container...
From: nico (nicolas.guillot_at_[hidden])
Date: 2015-05-19 15:15:37


I'm not sure of the title, because I'm not sure the issue comes from the
"copyablility" of my container.
I tryied quite everything but I can't get rid of this error.

Here is a simplified version of my code (please do not challenge the class
design, I really would like to keep the end-used syntax in the
BOOST_FOREACH):

    template <typename T>
    class MyContainer
    {
    public:
        typedef typename std::vector<T>::iterator iterator;
        typedef typename std::vector<T>::const_iterator const_iterator;

        MyContainer(std::vector<T>& vec, boost::mutex& mutex) :
            m_vector(vec),
            m_lock(mutex)
        {
        }

        iterator begin() { return m_vector.begin(); }
        const_iterator begin() const { return m_vector.begin(); }
        iterator end() { return m_vector.end(); }
        const_iterator end() const { return m_vector.end(); }

    private:
        std::vector<T>& m_vector;
        boost::lock_guard<boost::mutex> m_lock;
    };

    template <typename T>
    struct GetContainer
    {
        GetContainer(std::vector<T>& vec, boost::mutex& mutex) :
            m_vector(vec),
            m_mutex(mutex)
        {
        }

        MyContainer<T> Get()
        {
            return MyContainer<T>(m_vector, m_mutex);
        }

        std::vector<T>& m_vector;
        boost::mutex& m_mutex;
    };

    int main()
    {
        std::vector<int> v;
        v.push_back(1);
        v.push_back(2);
        boost::mutex m;

        GetContainer<int> getter(v, m);

        BOOST_FOREACH(int i, getter.Get())
        {
            std::cout << i << std::endl;
        }

        return 0;
    }

The compiler complains about not having a copy constructor
for MyContainer<int>::MyContainer(const MyContainer<int>&)
I also have :
error: no matching function for call to
‘MyContainer<int>::MyContainer(boost::foreach_detail_::rvalue_probe<const
MyContainer<int> >::value_type)’

I follow the extensibility tips:
http://www.boost.org/doc/libs/1_58_0/doc/html/foreach/extensibility.html#foreach.extensibility.making__literal_boost_foreach__literal__work_with_non_copyable_sequence_types

But, making MyContainer<T> : private boost::noncopyable
doesn't solve the issue.
Nor defining the function boost_foreach_is_noncopyable or specializing the
template struct is_noncopyable for MyContainer<int> (in fact, how would I
specialize this template for a template type ?)

Last "tip":
If I remove the mutex and the lock from everywhere (I just pass the vector
to GetContainer and to MyContainer<T>, it works.
But it doesn't work if I make MyContainer<T> : private boost::noncopyable
(I expected it should, so I'm not sure my problem is with BOOST_FOREACH,
but maybe because I return a copy of MyContainer with my getter ?)

I thank you if you read me until here, and thanks in advance for help.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk