Template class + delegating constructor = fields not initialized? (clang-tidy)

General Tech Bugs & Fixes 2 years ago

0 2 0 0 0 tuteeHUB earn credit +10 pts

5 Star Rating 1 Rating

Posted on 16 Aug 2022, this text provides information on Bugs & Fixes related to General Tech. Please note that while accuracy is prioritized, the data presented might not be entirely correct or up-to-date. This information is offered for general knowledge and informational purposes only, and should not be considered as a substitute for professional advice.

Take Quiz To Earn Credits!

Turn Your Knowledge into Earnings.

tuteehub_quiz

Answers (2)

Post Answer
profilepic.png
manpreet Tuteehub forum best answer Best Answer 2 years ago

 

I'm running clang-tidy 8.0 and I am getting the warning:

constructor does not initialize these fields:

when using a delegating constructor on a templated class. I want to know if this is a false positive I should suppress, or if indeed my code is wrong.

The example code in question is this:

template<typename T>
class A
{
public:
    explicit A(const std::size_t size) : 
        data_(nullptr),
        data_size_(size)
    {
        // ...
    }

    explicit A(const std::vector<T>& b) : 
        A(b.size())
    {
        // ...
    }

private:
    T* data_;
    std::size_t data_size_;
};

When running clang-tidy on this code:

clang-tidy-8 --checks=* test.cpp

I get, among other things:

warning: constructor does not initialize these fields: data_ [cppcoreguidelines-pro-type-member-init]
    explicit A(const std::vector<T>& b) : A(b.size()) {}

However, if I remove the template from the class and make it a normal class, then I don't get such error.

Is there something I'm missing when using delegating constructors on a templated class, or is this a bug in clang-tidy?

Thanks!

profilepic.png
manpreet 2 years ago

 

That's definitely a false positive. Your delegating constructor does indeed invoke another constructor which initializes both fields. However, I would consider just using a default initializer for _data in general anyways:

template<typename T>
class A
{
public:
    explicit A(std::size_t size) : 
        data_size_(size)
    {
        // …
    }

    explicit A(const std::vector<T>& b) : 
        A(b.size())
    {
        // …
    }

private:
    T* data_ = nullptr;
    std::size_t data_size_;
};

as that makes it even harder for anyone adding another constructor to forget to initialize data_. Unless, of course, there are some cases in which the member should remain uninitialized…

Also, note that the const on your const std::size_t size parameter in the first constructor of A is quite pointless.


0 views   0 shares

No matter what stage you're at in your education or career, TuteeHub will help you reach the next level that you're aiming for. Simply,Choose a subject/topic and get started in self-paced practice sessions to improve your knowledge and scores.