https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105683

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |DUPLICATE
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Reduced:

#include <vector>

namespace ossia
{
    struct value;

    struct value_variant_type {
        union Impl {
            std::vector<ossia::value> m_value8;
            Impl() { }
            ~Impl() { }
        } m_impl;

        value_variant_type() { }
        value_variant_type(const value_variant_type&) { }

        value_variant_type(const std::vector<ossia::value>& v); 
        value_variant_type(std::vector<ossia::value>&& v);

        value_variant_type& operator=(const value_variant_type&)
        { return *this; }

        value_variant_type& operator=(value_variant_type&& other);
    };

    struct value {
        value_variant_type v;

        value() { }

        value(const std::vector<ossia::value>& val) noexcept : v{val}
        {
        }

        explicit value(std::vector<ossia::value>&& val) noexcept :
v{std::move(val)}
        {
        }
    };


    inline value_variant_type::value_variant_type(const
std::vector<ossia::value>& v)
    {
        new (&m_impl.m_value8) std::vector<ossia::value>{v};
    }

    inline value_variant_type::value_variant_type(std::vector<ossia::value>&&
v)
    {
        new (&m_impl.m_value8) std::vector<ossia::value>{std::move(v)};
    }


    value_variant_type& value_variant_type::operator=(value_variant_type&&
other)
    {
        new (&m_impl.m_value8)
            std::vector<ossia::value>{std::move(other.m_impl.m_value8)};
        return *this;
    }

    inline ossia::value init_value()
    {
        return std::vector<ossia::value>{};
    }

    void create_value_inline(ossia::value& v) {
        v = ossia::init_value();
    }
}

int main()
{
    ossia::value v;
    create_value_inline(v);
}


The problem is that you have vector<value>{val} where val can be converted to
type value. The standard says that this should be interpreted as an
initializer-list for the value elements of the vector (even though val is
actually vector<value> and so you might copy construction). See PR 83264 for
the relevant Core defect reports.

My suggestion is to only use braced-init if you *really* want it, i.e. you are
specifically trying to call an initializer-list constructor, or you *really*
want narrowing checks.

For a type like vector with an initializer-list constructor, and a value type
that is constructible from everything under the sun (or like here, a specific
set of types that includes the vector<value> type), using braced-init is more
trouble than it's worth. It has no advantage, and serious disadvantages.

Anybody who tells you to always used braced-init because it's superior is
wrong.

*** This bug has been marked as a duplicate of bug 83264 ***

Reply via email to