Boost logo

Boost :

Subject: Re: [boost] [move] You can do it better: implementing push_back and handling implicit conversions
From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2011-03-09 12:18:53


El 08/03/2011 23:10, Stephan T. Lavavej escribió:
> Can you provide a minimal test case, demonstrating just the bug in question?

This compiles fine in GCC 4.4 and GCC 4.5 in -std=gnu++0x mode, but
fails on visual, since conversion provokes the instantiation of
conversion_target_movable's (private) copy constructor. I hope this helps:

#include <utility>
#include <memory>

class conversion_source
{
    public:
    conversion_source(){}
};

class conversion_target_movable
{
    conversion_target_movable (const conversion_target_movable&);
    conversion_target_movable operator=(const conversion_target_movable&);
    public:
    conversion_target_movable(){}
    conversion_target_movable(conversion_source){}
    conversion_target_movable(conversion_target_movable &&){}
    conversion_target_movable &operator=(conversion_target_movable &&)
    { return *this; }
};

template<class T>
class container
{
    public:

    void push_back(const T & x)
    { return priv_push_back(static_cast<const T&>(x)); }

    void push_back(T &&x)
    { return priv_push_back(::std::move(x)); }

    private:

    template<class U>
    void priv_push_back(U &&x)
       { ::new(&t) T(::std::forward<U>(x)); }
    T t;
};

int main()
{
    container<conversion_target_movable> c;
    {
       conversion_source x;
       c.push_back(x);
    }
    {
       const conversion_source x;
       c.push_back(x);
    }
    {
       c.push_back(conversion_source());
    }

    return 0;
}

the output is:

------ Build started: Project: move_bug, Configuration: Debug Win32 ------
1> move_bug.cpp
1>test.cpp(36): error C2248:
'conversion_target_movable::conversion_target_movable' : cannot access
private member declared in class 'conversion_target_movable'
1> test.cpp(13) : see declaration of
'conversion_target_movable::conversion_target_movable'
1> test.cpp(12) : see declaration of 'conversion_target_movable'
1> test.cpp(28) : see reference to function template
instantiation 'void container<T>::priv_push_back<const T&>(U)' being
compiled
1> with
1> [
1> T=conversion_target_movable,
1> U=const conversion_target_movable &
1> ]
1> test.cpp(28) : while compiling class template member
function 'void container<T>::push_back(const T &)'
1> with
1> [
1> T=conversion_target_movable
1> ]
1> test.cpp(44) : see reference to class template instantiation
'container<T>' being compiled
1> with
1> [
1> T=conversion_target_movable
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


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