问题
I have a class that's using an std::discrete_distribution
which can take an std::initializer_list
OR a couple of iterators. My class is in some ways wrapping the discrete_distribution
so I really wanted to mimic the ability to take an std::initializer_list
which would then be passed down.
This is simple.
However, the std::initializer_list
will always be constructed through some unknown values. So, if it was just a std::discrete_distribution
I would just construct from iterators of some container. However, for me to make that available via my class, I would need to templatize the class for the Iterator type.
I don't want to template my class because it's only occasionally that it would use the initializer_list
, and the cases where it doesn't, it uses an std::uniform_int_distribution
which would make this template argument, maybe confusing.
I know I can default the template argument, and I know that I could just define only vector::iterator
s if I wanted; I'd just rather not.
回答1:
According to the documentation, std::initializer_list cannot be non-empty constructed in standard C++. BTW, it is the same for C stdarg(3) va_list
(and probably for similar reasons, because variadic function argument passing is implementation specific and generally has its own ABI peculiarities; see however libffi).
In GCC, std::initializer_list
is somehow known to the C++ compiler (likewise <stdarg.h>
uses some builtin things from the C compiler), and has special support.
The C++11 standard (more exactly its n3337 draft, which is almost exactly the same) says in §18.9.1 that std::initializer_list
has only an empty constructor and refers to §8.5.4 list-initialization
You probably should use std::vector
and its iterators in your case.
As a rule of thumb and intuitively, std::initializer_list
is useful for compile-time known argument lists, and if you want to handle run-time known arguments (with the "number" of "arguments" unknown at compile time) you should provide a constructor for that case (either taking some iterators, or some container, as arguments).
If your class has a constructor accepting std::initializer_list<int>
it probably should have another constructor accepting std::vector<int>
or std::list<int>
(or perhaps std::set<int>
if you have some commutativity), then you don't need some weird templates on iterators. BTW, if you want iterators, you would templatize the constructor, not the entire class.
来源:https://stackoverflow.com/questions/29314156/c11-is-it-possible-to-construct-an-stdinitializer-list