开发者

C++0x initializer list passed by reference

I have tried to use C++0x initializer list as argument to a constructor call in this way:

Foo<float> foo("Foo 1", std::vector<const char *>({ "foo A", "foo B" }) );

with the constructor

Foo(const char *name, std::vector<const char *> &foos)

With this constructor the compiler complained:

error: no matching function for call to Foo<float>::Foo(
    const char [5], std::vector<const char *, std::allocator<const char *>开发者_如何学运维; >)
note: candidates are: Foo<T>::Foo(const char *, std::vector<const char *,
    std::allocator<const char *> >&) [with T = float]

However, when I've changed the constructor to

Foo(const char *name, std::vector<const char *> foos)

Everything worked as expected. Why does the first constructor not work? I thought the vector could be constructed in the place of constructor call and passed down by reference, but obviously there's some problem. Could anybody explain that?

Thanks

Btw. I am using g++ version 4.4.5

EDIT: Thanks to the correct answers below, I have found also why I can't do that.


You cannot bind a temporary to a T&.

You can bind a temporary to T const&:

Foo(const char* name, std::vector<const char*> const& foos)

But I'd question the sanity of a vector of char pointers. What's wrong with std::string?


Temporary cannot be bound to non-const reference, so do this:

Foo(const char *name, const std::vector<const char *> &foos)
                    //^^^^ note this


The initializer list is a red hering, I think. You are trying to bind a temporary to a non-const reference, which is illegal. Try using a const reference.

Foo(const char *name, std::vector<const char *> const& foos)


std::vector<const char *> &foos is lvalue reference. You are trying to pass rvalue, this is wrong. You can use either rvalue reference std::vector<const char *> &&foos or const reference const std::vector<const char *> &foos


You cannot bind an rvalue std::vector to a non-const lvalue reference. You must take a const lvalue reference or an rvalue reference.


You already have your answer, but since you have "initializer list" in the title, you may want to consider writing a (C++0x) initializer-list constructor, e.g. like so:

struct Foo {
    Foo(const char* name, std::initalizer_list<const char*> il)
      : name(name), buf(il)
    { }
private:
    const char * const name;
    std::vector<const char *> buf;
};

Then you're no longer an aggregate, but you can construct it like so:

Foo x("Name", { "ab", "cd", "ef" });

You even pass il as const-reference if you prefer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜