Use initializer list to create single item vector

家住魔仙堡 提交于 2019-12-10 17:13:04

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!