Home > Mobile >  const object as a data member vs normal variable
const object as a data member vs normal variable

Time:03-15

I was trying to make a Container class that will be using an object of a class Comparator which will be passed through the template.

So I am doing something like:

template<typename T>
class Container{
    const T c;
};


struct Comparator{
    public:
    bool operator()(const int a, const int b)const{
        return a < b;
    }
};

int main(){
    Container<Comparator> container;
    return 0;
}

When I am trying to compile this code I am getting the following error:

e.cpp:28:27: error: uninitialized const member in 'class Container<Comparator>'
   28 |     Container<Comparator> container;
      |                           ^~~~~~~~~
e.cpp:16:13: note: 'const Comparator Container<Comparator>::c' should be initialized
   16 |     const T c;
      |      

To get rid of this error what I did is just added a default constructor in the Comparator class:

struct Comparator{
    public:
    Comparator(){
        
    }
    bool operator()(const int a, const int b)const{
        return a < b;
    }
};

But the weird thing I observed is that when I am making a const object of the class Comparator as a normal variable (not the data member of any class) I am not getting any kind of error.

struct Comparator{
    public:
    bool operator()(const int a, const int b)const{
        return a < b;
    }
};

int main(){
    const Comparator comp;
    return 0;
}

So my question is why I am getting errors when making a const object of the Comparator type within a class and not when making a normal const object of the same type?

CodePudding user response:

If no initializer is given for the const Comparator variable it must be const-default-constructible. But your class Comparator is const-default-constructible because it has no non-static data members. For actual rules determining that see [dlc.init.general]/7.

This is not only the requirement for such a variable, but also the requirement to not cause the implicit default constructor to be deleted if a class has an analogues non-static member without initializer, see [class.default.ctor]/2.4.

So your original code should compile. MSVC does compile it, but GCC and Clang do not.

The relevant requirement for the class members was however changed to the referenced wording with a defect report: CWG 2394. Before that it required the member to have a user-provided default constructor, which is a stronger requirement than being const-default-constructible and which is exactly what you did add to make it work.

According to both the Clang implementation status page and the GCC implementation status page the status of their implementation of the DR is unknown.

  • Related