After constructing an object with a moving constructor, the new object should "steal" the resources of the "source" object, which is then left in an indefinite (but valid) state.
For example:
#include <iostream>
#include <vector>
template <class T>
void print(const std::vector<T>& v)
{
    std::cout << "size = " << v.size() << " vector = ";
    for (const auto& x : v)
        std::cout << x << " ";
    std::cout << std::endl;
}
int main()
{
    std::vector<int> data(10, 3);
    std::cout << "data:" << std::endl;
    print(data);
    std::vector<int> data2(std::move(data));
    std::cout << "data2:" << std::endl;
    print(data2);
    std::cout << "data after moving:" << std::endl;
    print(data);
    return 0;
}
See it live on Coliru.
As far as I know the standard does not specify the content of data after having called the moving constructor, however one would expect that the resources of data have been stolen by data2. And indeed, the output the program above shows that:
data:
size = 10 vector = 3 3 3 3 3 3 3 3 3 3 
data2:
size = 10 vector = 3 3 3 3 3 3 3 3 3 3 
data after moving:
size = 0 vector = 
Now consider a slight variation of the above program:
#include <iostream>
#include <vector>
class A {
    std::vector<int> m_data;
public:
    A(std::vector<int>&& data) : m_data{data} { }
    const std::vector<int>& data() const { return m_data; }
};
template <class T>
void print(const std::vector<T>& v)
{
    std::cout << "size = " << v.size() << " vector = ";
    for (const auto& x : v)
        std::cout << x << " ";
    std::cout << std::endl;
}
int main()
{
    std::vector<int> data(10, 3);
    std::cout << "data:" << std::endl;
    print(data);
    A x{std::move(data)};
    std::cout << "x.data():" << std::endl;
    print(x.data());
    std::cout << "data after moving:" << std::endl;
    print(data);
    return 0;
}
See it live on Coliru.
I am surprised by output of the program:
data:
size = 10 vector = 3 3 3 3 3 3 3 3 3 3 
x.data():
size = 10 vector = 3 3 3 3 3 3 3 3 3 3 
data after moving:
size = 10 vector = 3 3 3 3 3 3 3 3 3 3 
It looks like the vector data has been just copied to A::m_data rather then being moved.
If I substitute the moving constructor of A with
A(std::vector<int>&& data) : m_data{std::move(data)} { }
(see it live on Coliru)
or with
A(std::vector<int>&& data) : m_data{std::forward<std::vector<int>&&>(data)} { }
(see it live on Coliru)
then the output of the program resembles that of the first code
data:
size = 10 vector = 3 3 3 3 3 3 3 3 3 3 
x.data():
size = 10 vector = 3 3 3 3 3 3 3 3 3 3 
data after moving:
size = 0 vector = 
In other words, it seems that either std:move or std::forward are necessary to effectively call the moving constructor of A::m_data. Both std::move and std::forward return a static_cast to std::vector<int>&&, but the argument of the moving constructor of A is already a rvalue.
Why is an additional std::move or std::forward necessary?
 
    