Привет
Почему так не работает?
struct movable
{
};
class one
{
public:
one(movable&& m)
: _m(m)
{}
movable _m;
};
class creator
{
public:
template<typename S, typename ... Args>
static S* create(Args ... args)
{
return new one(args ...);
}
};
int main(int argc, char** argv)
{
movable m;
creator::create<one, movable&&>(std::forward<movable>(m));
return 0;
}
1>probe.cpp(442): error C2664: 'one::one(const one &)' : cannot convert argument 1 from 'moveable' to 'moveable &&'
MS VS 2013
Как можно сделать, чтобы работало?
Здравствуйте, Logot, Вы писали:
L>MS VS 2013
L>Как можно сделать, чтобы работало?
Проверил на
2015
#include <utility>
struct movable
{
};
class one
{
public:
one(movable&& m)
: _m(m)
{}
movable _m;
};
class creator
{
public:
template<typename S, typename ... Args>
static S* create(Args ... args)
{
return new one(std::move(args ...));
}
};
int main(int , char** )
{
movable m;
creator::create<one, movable&&>(std::forward<movable>(m));
return 0;
}
Здравствуйте, Igore, Вы писали:
I>Здравствуйте, Logot, Вы писали:
L>>MS VS 2013
L>>Как можно сделать, чтобы работало?
I>Проверил на 2015
I>I>#include <utility>
I>struct movable
I>{
I>};
I>class one
I>{
I>public:
I> one(movable&& m)
I> : _m(m)
I> {}
I> movable _m;
I>};
I>class creator
I>{
I>public:
I> template<typename S, typename ... Args>
I> static S* create(Args ... args)
I> {
I> return new one(std::move(args ...));
I> }
I>};
I>int main(int , char** )
I>{
I> movable m;
I> creator::create<one, movable&&>(std::forward<movable>(m));
I> return 0;
I>}
I>
но на самом деле у меня one принимает несколько параметров
Здравствуйте, Logot, Вы писали:
L>но на самом деле у меня one принимает несколько параметров
Тогда так
#include <utility>
struct movable
{
};
struct notMovable
{
};
class one
{
public:
one(movable&& m,notMovable nm)
: _m(m), _nm(nm)
{}
movable _m;
notMovable _nm;
};
class creator
{
public:
template<typename S, typename ... Args>
static S* create(Args ... args)
{
return new one(std::forward<Args>(args)...);
}
};
int main(int , char** )
{
movable m;
notMovable nm;
creator::create<one, movable&&,notMovable>(std::forward<movable>(m),nm);
return 0;
}
Здравствуйте, Igore, Вы писали:
На самом деле у Вас тоже не совсем корректно )
#include <utility>
struct movable
{
movable() = default;
movable(movable&&) = default;
movable& operator=(movable&&) = default;
movable(const movable&) = delete;
movable& operator=(const movable&) = delete;
};
struct notMovable
{
notMovable() = default;
notMovable(const notMovable&) = default;
notMovable& operator=(const notMovable&) = default;
notMovable(notMovable&&) = delete;
notMovable& operator=(notMovable&&) = delete;
};
class one
{
public:
one(movable&& m,notMovable nm)
// Хоть переменная m и попала сюда через перемещение здесь она уже имеет имя/адрес т.е. она как бы lvalue
// поэтому для последующего перемещения её используем std::forward
: _m(std::forward<movable>(m)), _nm(nm)
{}
movable _m;
notMovable _nm;
};
class creator
{
public:
template<typename S, typename ... Args>
static S* create(Args&& ... args) // Здесь необходимо указать семантику перемещения, иначе все в функцию попадает через конструктор копирования
{
return new one(std::forward<Args>(args)...);
}
};
int main(int , char** )
{
movable m;
notMovable nm;
creator::create<one>(std::move(m),nm); // В параметрах шаблона не нужно указывать перемещение, т.к. переменная m находится на стеке (lvalue) её перемещаем явно
return 0;
}
Вот теперь переменная
m только перемещается!