首页 > 解决方案 > 无法调用 initializer_list 构造函数

问题描述

相关:

为什么我得到一个“没有构造函数实例匹配 MyArray::MyArray”参数列表?

为什么`std::initializer_list`经常按值传递?

错误 C2440:“正在初始化”:无法从“初始化列表”转换为“std::vector<char *,std::allocator<_Ty>>”

为什么:

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"),
    };
}

宏扩展为:

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);
                }
            }
    }
};

给出错误信息:

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

端口是一个结构:

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);
    }

};
}

构造函数实现为:

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

代码看起来正确;仅使用 initializer_list 进行宏扩展似乎没有任何问题,但我看不出是什么。

标签: c++

解决方案


该错误是 MSVC 抱怨它实际上无法将该列表转换为Port使用给定的初始化器列表进行初始化的方式,这意味着类型不匹配以及类型成员和列表成员之间缺乏可用的转换。


推荐阅读