I had a class with a std::vector member that had the same name as the class and had no user-defined constructors; later I had a factory method that generated one of these objects:
#include <vector>
class data {
std::vector<int> data;
};
data create()
{
data d{};
// ...
return d;
}
When I try to build this with Visual Studio 2017 (15.9.19), it fails to compile with:
error C2664: 'data::data(data &&)': cannot convert argument 1 from 'std::vector<int,std::allocator<int>>' to 'const data &'
note: Reason: cannot convert from 'std::vector<int,std::allocator<int>>' to 'const data'
note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
note: This diagnostic occurred in the compiler generated function 'data::data(data &&)'
On Compiler Explorer, this code also failed on MSVC 2019, but does compile in GCC 10.2. So is this a bug in MSVC, is it not standard compliant code, or is this behaviour "implementation dependent"?
Both MSVC and GCC give clear errors that a class with user-declared constructors can't have a member of the same name, but what if the class just has compiler generated constructors? And what about declaring constructors as either default or delete, does that still count as user-declared?
BTW, I notice that the behaviour of MSVC was different if I changed the type of the member from std::vector, so this definition did compile:
class data {
int data;
};
And likewise if the factory just returned an rvalue rather than a local, MSVC again did compile it:
data create() { return {}; }