Will / C ++ 11/14 support something like vector <auto>
It is not directly supported, and it is not immediately clear what exactly you want.
The comments already mentioned several features (such as the Boost any and variant classes) for creating heterogeneous collections. Hope this is not what you need, because heterogeneous collections do not mix well with C ++, so using them is ugly and awkward. I believe that there are cases / situations where this is really the best choice, but at least in my experience, these cases are quite rare.
Another possible interpretation of what you might need is a vector that (for example, auto in the general case) has exactly one type, but this type is inferred from the initializer, so if you initialized the vector from some int s, you will get vector<int> , and if you initialized it from several lines, you will get vector<string> and so on. Although the language does not directly support this, it is fairly easy to imitate it, at least to some extent. Template classes cannot / cannot infer 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 this type. For instance:
template <class T> std::vector<T> make_vector(std::initializer_list<T> init) { return std::vector<T>(init); } This returns vector<T> (with T inferred from the data type 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> The latter requires the custom literal operator to be new in C ++ 14 (which many compilers do not yet support). The rest should be fine with C ++ 11.
There was also some discussion (and a suggestion in N3602 ) of adding a feature (possibly in C ++ 17) where you could define something like make_vector above, but as something like a template constructor for a class. This will allow you to use the argument output in the constructor to output the template parameter for the class as a whole, so you can do something like:
X x(1); // deduces as X<int> X x(2.0) // deduces as X<double> Warning: this has been proposed but not accepted. It can (easily) never be accepted - and even if it is, it can be significantly modified before this happens.
No, not in C ++ 11 or C ++ 14, which are already completed and published.
But it is possible that vector<auto> and similar things, such as tuple<auto...> , will be in C ++ 17 as part of work on concepts.
This is quite natural because std::vector<T> can be used in function templates and partial specializations of class templates, where T is a template parameter, and also because polymorphic lambdas allow auto as a parameter of type function (which is an abbreviation for a function template with derived parameters).
TS concepts allow you to declare a "common function" as follows:
auto func(auto arg); Since you may have a function template like this:
template<typename T> auto func(std::vector<T> v); it makes sense to extend the syntax of common functions to:
auto func(std::vector<auto> v); and after you enable this 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 this is not in C ++ 11 is because auto was new and would be too ambitious to try to do too much. In C ++ 14, polymorphic lambdas were new, and, again, expanding the use of auto would be more ambitious.
For C ++ 17, we have more experience using auto in real code, and the compiler authors are familiar with its implementation and know what is possible without much effort.
A boost::any can store an instance of any type that can be copied, which is a lot of types.
To get data from your any , you need to know the exact type that you stored in it.
Writing a simple any not difficult:
#include <memory> #include <utility> struct any_internal { virtual any_internal* clone() const = 0; virtual ~any_internal() {}; }; template<class T> struct any_details; class any { std::unique_ptr<any_internal> internal; public: any() = default; any( any && ) = default; any( any const&& o):any(o) {} any( any & o ):any( const_cast<any const&>(o) ) {} any& operator=( any && ) = default; any& operator=( any const&& o ) { return this->operator=( o ); }; any& operator=( any & o ) { return this->operator=( const_cast<any const&>(o) ); }; any( any const& o ):internal( o.internal?o.internal->clone():nullptr ) {} any& operator=( any const& o ) { any tmp(o); using std::swap; swap( internal, tmp.internal ); return *this; } template<class U> void reset( U&& o ); template<class U, class... Args> void emplace( Args&&... args ); template<class U> any( U&& o ); template<class U> any& operator=(U&& o); template<class T> T* get(); template<class T> T const* get() const; template<class T> T* fast_get(); template<class T> T const* fast_get() const; explicit operator bool() const { return internal!=nullptr; } }; template<class T> struct any_details : any_internal { T t; template<class...Args> any_details( Args&&... args ):t(std::forward<Args>(args)...) {} any_internal* clone() const override { return new any_details<T>{t}; } }; template<class U, class... Args> void any::emplace( Args&&... args ) { internal.reset( new any_details<U>( std::forward<Args>(args)... ) ); } template<class U> void any::reset( U&& o ) { emplace<typename std::decay<U>::type>( std::forward<U>(o) ); } template<class U> any::any( U&& o ) { reset( std::forward<U>(o) ); } template<class U> any& any::operator=(U&& o) { reset( std::forward<U>(o) ); return *this; } template<class T> T* any::get() { auto* r = dynamic_cast< any_details<T>* >( internal.get() ); if (r) return &r->t; return nullptr; } template<class T> T const* any::get() const { auto* r = dynamic_cast< any_details<T>* >( internal.get() ); if (r) return &r->t; return nullptr; } template<class T> T* any::fast_get() { auto* r = static_cast< any_details<T>* >( internal.get() ); if (r) return &r->t; return nullptr; } template<class T> T const* any::fast_get() const { auto* r = static_cast< any_details<T>* >( internal.get() ); if (r) return &r->t; return nullptr; } and std::vector<any> behave the same way you might want to make std::vector<auto> .
Increased efficiency can be achieved with small buffer optimizations (i.e. keep T within any if T is small, instead of using heap).
You probably also want to split get into fast_get , where get does dynamic_cast and fast_get does static_cast again for efficiency. (If you know for sure, you can fast_get )
This is mostly condensed void* .