Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generated constructors if class has a member with same name as class

Tags:

c++

visual-c++

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 {}; }
like image 399
PCB Avatar asked Nov 16 '22 03:11

PCB


1 Answers

According to the standard class.mem#21

if class T has a user-declared constructor, every non-static data member of class T shall have a name different from T.

So your code above is valid, and the compiler must accept it. Bug reported: https://developercommunity.visualstudio.com/t/generated-constructors-if-class-has-a-member-with/1626621

what about declaring constructors as either default or delete, does that still count as user-declared?

Yes, these are also considered as user-declared constructors.

like image 73
Fedor Avatar answered Dec 14 '22 23:12

Fedor