Sebi
Sebi

Reputation: 4532

Cannot call initializer_list constructor

Related to:

why am i getting a "no instance of constructor matches the MyArray::MyArray" argument list?

why is `std::initializer_list` often passed by value?

error C2440: 'initializing': cannot convert from 'initializer list' to 'std::vector<char *,std::allocator<_Ty>>'

Why does:

int main()
{
    rtosc::Ports p = { // <== error C2440: 'initializing': cannot convert from 'initializer list' to 
                       // 'rtosc::Ports'
        rParamF(foo, rLinear(-1,10), "no documentation"), // <== macro 
                                                        // expansions look ok
        rParamF(bar, rLinear(0, 100.2), "no doc"),
    };
}

macros expand to:

rtosc::Ports p = {      
    {
        "foo" "::f",
        ":" "parameter" "\0"
        ":documentation\0="
        ":" "min" "\0=" "-1" "\0"
        ":" "max" "\0=" "10" "\0"
        ":" "scale" "\0=" "linear" "\0",
        "no documentation" "\0",
        0,
        [](
            const char *msg,
            rtosc::RtData &data)
            {
                (void)msg;
                (void)data;
                rObject *obj = (rObject*)
                data.obj;
                (void)obj;
                const char *args = rtosc_argument_string(msg);
                (void)args;
                const char *loc = data.loc;
                (void)loc;
                auto prop = data.port->meta();
                (void)prop;
                if (!strcmp("", args))
                {
                    data.reply(loc, "f", obj->foo);
                }
                else
                {
                    decltype(obj->foo)
                    var = rtosc_argument(msg, 0).f;
                    if (prop["min"] && var < (decltype(var))
                        atof(prop["min"]))
                        var = (decltype(var))
                        atof(prop["min"]);
                    if (prop["max"] && var > (decltype(var))
                        atof(prop["max"]))
                        var = (decltype(var))
                        atof(prop["max"]);
                    if ((decltype(var))(obj->foo) != var)
                        data.reply("/undo_change",
                        "s" "f" "f",
                        data.loc,
                        static_cast<int>(obj->foo),
                        var);
                    obj->foo = var;
                    data.broadcast(loc, "f", obj->foo);
                }
            }
    }
};

gives the error message:

error C2440: 'initializing': cannot convert from 'initializer list' to 'rtosc::Ports'

Ports is a struct:

namespace rtosc {
    struct Ports
    {
        std::vector<Port> ports;

        Ports(std::initializer_list<Port> l);

      protected:
        void refreshMagic(void);
      private:
        //Performance hacks
        class Port_Matcher *impl;
        unsigned elms;
    }

struct Port {
    const char  *name;    //!< Pattern for messages to match
    const char  *metadata;//!< Statically accessable data about port
    const Ports *ports;   //!< Pointer to further ports
    std::function<void(msg_t, RtData&)> cb;//!< Callback for matching functions

    class MetaIterator
    {
    public:
        MetaIterator(const char *str);

        //A bit odd to return yourself, but it seems to work for this
        //context
        const MetaIterator& operator*(void) const { return *this; }
        const MetaIterator* operator->(void) const { return this; }
        bool operator==(MetaIterator a) { return title == a.title; }
        bool operator!=(MetaIterator a) { return title != a.title; }
        MetaIterator& operator++(void);
        operator bool() const;

        const char *title;
        const char *value;
    };

    class MetaContainer
    {
    public:
        MetaContainer(const char *str_);

        MetaIterator begin(void) const;
        MetaIterator end(void) const;

        MetaIterator find(const char *str) const;
        size_t length(void) const;
        //!Return the key to the value @p str, or NULL if the key is
        //!invalid or if there's no value for that key.
        const char *operator[](const char *str) const;

        const char *str_ptr;
    };

    MetaContainer meta(void) const
    {
        if (metadata && *metadata == ':')
            return MetaContainer(metadata + 1);
        else
            return MetaContainer(metadata);
    }

};
}

with the constructor implemented as:

Ports::Ports(std::initializer_list<Port> l)
    :ports(l), impl(NULL)
{
    refreshMagic();
}

The code looks correct; there doesn't seem to be anything wrong with the macro expansion only with initializer_list but I don't see what.

Upvotes: 0

Views: 333

Answers (1)

Swift - Friday Pie
Swift - Friday Pie

Reputation: 14708

That error is the way of MSVC complain that it cannot actually convert that list to initialize Port with given initializer list, which means type mismatch and lack of available conversion between members of type and members of list.

Upvotes: 1

Related Questions