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.
精彩评论