Why does passing a reference through a conditional operator to the initializer list generate a warning?

The following code results in this warning (vc and gcc -Wextra):

warning C4413: 'ReferencingContainer::_vector' : reference member is initialized to a temporary that doesn't persist after the constructor exits

      

But I don’t understand why. I thought I was only passing the link.

#include <vector>

struct Referencing
{
    Referencing(int const &x) : _x(x) {}
    Referencing(int const &x, int dummy) : _x(x > 5 ? x : throw "error") {} // bad code, warning is ok

    int const &_x;
};

struct Container
{
    std::vector<double> _vector;
};

struct ReferencingContainer
{
    ReferencingContainer(Container const &container)
        : _container(container)
        , _vector(container._vector.size() > 0 ? container._vector : throw "error")  // <-- warning occurs here
    {}

    Container const &_container;
    std::vector<double> const &_vector;
};

int main()
{
    Referencing test1(21);
    Referencing test2(22, 0);

    Container container;
    ReferencingContainer referencingContainer(container);

    return 0;
}

      

Why is the compiler unhappy with my code? Should I really be worried about my object being referenced to a temporary one?

+3


source to share


1 answer


If you add a flag Wextra

, you get this warning:

px.cpp:12:83: warning: a temporary bound to ‘ReferencingContainer::_vector’ only persists until the constructor exits [-Wextra]
         , _vector(container._vector.size() > 0 ? container._vector : throw "error") // <--- warning occurs here!

      

which is a compiler error, according to this question:

False warning about binding temporary reference element to constructor

However, as vsoftco pointed out, the warning persists in version 5.1

Other topical issues:




A possible quick fix is ​​to pass a pointer from the expression ?: and then locate it.

, _vector(*(container._vector.size() > 0 ? &container._vector : throw "error"))

      




So what's the problem?

The compiler tells you they are usually polite to us. By reference to std :: vector :: size , we have:

size_type size () const;

which means when you call it on line, it generates an alert, size()

returns a copy of the size _vector

that goes out of scope when you exit the scope constructor.

+3


source







All Articles