Template Designer Compared to Copy Designer Template

I have a class with a template constructor for implicitly converting a move, however this constructor should NOT be used for a class (which should only be constructive for copying). However, the compiler always tries to use a template constructor instead of the usual copy constructor.

eg. With this, I get the following compiler errors, link . (you can just copy this code if you want to try)

struct implementation{};
class my_class
{
 my_class(my_class&&); // delete move-constructor... OUCH... COMPILER ERROR
public:
 my_class(){}
 my_class(const my_class& other) : impl_(other.impl_){}

 template<typename T>
 my_class(T&& impl) : impl_(std::make_shared<T>(std::move(impl))){} // Still tries to use this...

private:
 std::shared_ptr<implementation> impl_;
};

class other_class
{
public:
 my_class foo()
 { 
       return instance_; // Wants to use move-constructor???
 }
private:
 my_class instance_;
};

Has anyone understood how to solve this correctly?

+3
source share
2 answers

, my_class:

class my_class
{
public:
    my_class() {}
    my_class(my_class&& that) : impl_(std::move(that.impl_)) {}

    template <typename T> my_class(T&& impl,
    typename std::enable_if<
        std::is_base_of<
            implementation,
            typename std::remove_reference<T>::type
        >::value,
        void
    >::type* dummy = 0
    ) : impl_(std::make_shared<T>(std::forward<T>(impl))) {}

    template <typename T>
    typename std::enable_if<
        std::is_base_of<
            implementation,
            typename std::remove_reference<T>::type
        >::value,
        my_class&
    >::type
    operator=(T&& impl)
    {
        std::make_shared<implementation>(std::forward<T>(impl)).swap(impl_);
        return *this;
    }

private:
    std::shared_ptr<implementation> impl_;
};

, lvalue rvalue, std::forward std::move. remove_reference , lvalue T , derived& base, derived ( ).

+4

:

template<typename T>
my_class(typename std::enable_if<std::is_base_of<implementation, derived_1>::value, T&&>::type impl) : impl_(std::make_shared<T>(std::move(impl)))  {}

template <typename T> 
my_class& operator= (typename std::enable_if<std::is_rvalue_reference<T&&>::value && !std::is_same<T, my_class>::value, T&&>::type impl)

, T . , T, , , Anything<T>::type.

, enable_if , :

template <class T>
typename enable_if<..., T&>::type operator=(const T&);

( ) , :

template <class T>
MyClass(const T&, typename enable_if<..., void>::type* =0);

FredOverflow .

, rvalue-, std::forward std::move. . . ( FredOverflow):

template <typename T>
typename std::enable_if<std::is_base_of<implementation, T>::value, my_class&>::type
operator=(T&& impl)
{
    std::make_shared<implementation>(std::forward<T>(impl)).swap(impl_);
    return *this;
}
+2

Source: https://habr.com/ru/post/1779791/


All Articles