问题
I have a function func
which is overloaded to take either a std::vector<Obj>
argument or a Obj
argument.
#include <vector>
#include <iostream>
class Obj {
int a = 6;
};
void func(const std::vector<Obj>& a) {
std::cout << "here" << std::endl;
}
void func(const Obj& a) {
std::cout << "there" << std::endl;
}
int main() {
Obj obj, obj2;
func({obj});
func({obj, obj2});
}
Actual output:
there
here
Expected output:
here
here
It seems {obj}
doesn't initialize a vector, but rather an object. I guess there is some priority order when it comes to which type it initializes. How do I control it precisely?
(Examples compiled with g++ (Ubuntu 8.3.0-6ubuntu1) 8.3.0.)
I found a possible duplicate (c++11 single element vector initialization in a function call), although my question remains unanswered:
I understand that {obj}
can resolve to an object rather a vector of a single element and the former takes priority. But is there a way to use {}
to create a single item vector (so that foo
resolves to the std::vector
overload)? I could create a vector explicitly but {}
seems nicer.
回答1:
As mentioned in the linked question duplicate (the original) there is no way to force the resolution in favour of the overload taking std::initializer_list
.
The original signatures (using int
to simplify):
void func(const std::vector<int> &a);
void func(const int &a);
Since I have encountered this many times I typically do this:
func(std::vector<int>{10});
I am not aware of any shorter way of doing this because using actual type std::initializer_list
that would do the same is even more verbose. But on the birght side it at least makes what you are doing perfectly clear since {10}
is really ambiguous if not accompanied with the type.
回答2:
You can't.
Excerpt (from here, emphasis mine):
"[...] if the initializer list has a single element of type E and either T is not a reference type or its referenced type is reference-related to E, the object or reference is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization)"
Therefore, in your linked example, {obj}
will "decay" to obj
and the overload will resolve to void func(const Obj& a)
.
As stated in the other answer, you can explicitely call func(std::vector {obj})
to call the vector overload instead.
来源:https://stackoverflow.com/questions/55700589/use-initializer-list-to-create-single-item-vector