I am wondering if c++11/c++14 would/already support something like vector<auto>
?
If not, Is there any reason?
It's not supported directly, and not immediately clear exactly what you want it to do.
Comments have already mentioned a couple of possibilities (such as Boost any
and variant
classes) for creating heterogeneous collections. I hope this isn't what you were after, because heterogeneous collections fit poorly with C++ so using them is ugly and clumsy. I suppose there are cases/situations where these really would be the best choices available, but at least in my experience, those cases are fairly rare.
Another possible interpretation of what you might want would be a vector that (like auto
in general) holds exactly one type, but that type is deduced from the initializer, so if you initialized the vector from some int
s, you'd get a vector<int>
, and if you initialized it from some strings, you'd get a vector<string>
, and so on. Although the language doesn't support that directly, it is pretty easy to simulate it to at least some degree. Template classes can't/don't ever deduce template parameters, but template functions do/can. Therefore, we can create a tiny function template to take some initializers, deduce their type, and return a vector of that type. For example:
template <class T>
std::vector<T> make_vector(std::initializer_list<T> init) {
return std::vector<T>(init);
}
This returns a vector<T>
(with T
deduced from the type of data in the initializer list), so you can do things like:
auto a = make_vector({ 1, 2, 3, 4 }); // a -> vector<int>
auto b = make_vector({ 1.0, 2.0, 3.0 }); // b -> vector<double>
auto c = make_vector({ "1"s, "2"s, "3"s }); // c -> vector<std::string>
That last one requires a user-defined literal operator that's new in C++14 (which many compilers don't yet support). The rest should be fine with C++11.
There has also been some discussion (and a proposal in N3602) of adding a capability (perhaps to C++17) where you'd be able to define something like the make_vector
above, but as something like a templated constructor for the class. This would let you use argument deduction on the constructor to deduce the template parameter for the class as a whole, so you'd be able to do something like:
X x(1); // deduces as X<int>
X x(2.0) // deduces as X<double>
Warning though: this has been proposed but not accepted. It may (easily) never be accepted--and even if it is, it may be altered significantly before that happens.
No, not in C++11 or C++14, which are already finished and published.
But it's possible that vector<auto>
and similar things like tuple<auto...>
will be in C++17 as part of the Concepts work.
It follows quite naturally from the fact that std::vector<T>
can be used in function templates and class template partial specializations where T
is a template parameter, and also from the fact that polymorphic lambdas allow auto
as a function parameter type (which is shorthand for a function template with deduced parameters).
The Concepts TS allows a "generic function" to be declared like:
auto func(auto arg);
Since you can have a function template like this:
template<typename T>
auto func(std::vector<T> v);
it makes sense to extend the generic function syntax to allow:
auto func(std::vector<auto> v);
and once you allow that in a function declaration, it should also be possible to allow it in variable declarations:
std::vector<auto> v = function_returning_vector_of_something();
The reason it isn't in C++11 is that auto
was new, and it would have been too ambitious to try and make it do too much. In C++14 polymorphic lambdas were new, and again, expanding the uses of auto
any further would have been ambitious.
For C++17 we have more experience with using auto
in real code, and compiler writers are familiar with implementing it and know what is possible without too much effort.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With