Is it possible to have an "auto" member variable?

For example I wanted to have a variable of type auto because I'm not sure what type it will be. When I try to declare it in class/struct declaration it's giving me this error:

Cannot deduce auto type. Initializer required
Is there a way around it?
struct Timer < auto start; >; 
asked Aug 13, 2013 at 2:31 39.2k 23 23 gold badges 77 77 silver badges 123 123 bronze badges Isn't that what templates are for? Commented Aug 13, 2013 at 2:34

When do you find out what type it will be? Compile time or run time? Can you give us some context? What are you trying to do?

Commented Aug 13, 2013 at 2:35 What is sizeof(Timer) ? Commented Aug 13, 2013 at 2:36 What would that mean? Commented Aug 13, 2013 at 2:38 @Oleksiy plz give more description. Why can't you decide its type? Commented Aug 13, 2013 at 2:38

6 Answers 6

You can, but you have to declare it static and const :

struct Timer < static const auto start = 0; >; 

With this limitation, you therefore cannot have start as a non-static member, and cannot have different values in different objects.

If you want different types of start for different objects, better have your class as a template

template struct Timer < T start; >; 

If you want to deduce the type of T , you can make a factory-like function that does the type deduction.

template Timer::type> MakeTimer(T&& startVal) < // Forwards the parameter return Timer::type>(startVal)>; > 
answered Aug 13, 2013 at 2:33 Mark Garcia Mark Garcia 17.7k 4 4 gold badges 59 59 silver badges 95 95 bronze badges

Is there anything fundamental that prevents auto non static members from being allowed in the standard assuming they are initialized at point of declaration ?

Commented Jul 31, 2022 at 6:07

@user3882729 Imo an auto member would make it pretty unclear that it's actually a template, unlike a function template which just have auto at it's first line.

Commented Mar 24, 2023 at 16:12

Actually, it would be nice, if a future version of the C++ standard allowed auto also on non-static members, if an initializer is present, as in this simple example:

class C < auto a < 0.0 >; auto b < 3U >; >; 

This would be equivalent to:

class C < decltype(0.0) a < 0.0 >; decltype(3U) b < 3U >; >; 

and would save some typing in certain cases, especially, where the initializing expressions are not as simple as here. Of course, the in-class initializers can later be overridden in constructors, but for the typing of the class members, the in-class initializers should take precedence.

answered May 8, 2022 at 11:00 Kai Petzke Kai Petzke 2,714 1 1 gold badge 27 27 silver badges 30 30 bronze badges

I second that ! Now that we can declare almost any variable with auto, like: auto varName = DatyType < value >; we should be able to do the same for class members

Commented Sep 21, 2023 at 10:55

If you declare a class in a lambda expression, you can infer the types of member variables using decltype :

#include #include #include using namespace std; auto generic_class = [](auto width1, auto height1) < class local_class < public: decltype(width1) width; decltype(height1) height; >local; local.width = width1; local.height = height1; return local; >; int main() < auto obj1 = generic_class(3,std::string("Hello!")); auto obj2 = generic_class(std::vector,true); cout
answered Sep 30, 2021 at 18:51 Anderson Green Anderson Green 31.6k 69 69 gold badges 208 208 silver badges 336 336 bronze badges This code can really mess with someone's head Commented Mar 28, 2022 at 4:22

This is what the C++ draft standard has to say about using auto for member variables, in section 7.1.6.4 auto specifier paragraph 4 :

The auto type-specifier can also be used in declaring a variable in the condition of a selection statement (6.4) or an iteration statement (6.5), in the type-specifier-seq in the new-type-id or type-id of a new-expression (5.3.4), in a for-range-declaration, and in declaring a static data member with a brace-or-equal-initializer that appears within the member-specification of a class definition (9.4.2).

Since it must be initialized this also means that it must be const . So something like the following will work:

struct Timer < const static int start = 1; >; 

I don't think that gets you too much though. Using template as Mark suggests or now that I think about it some more maybe you just need a variant type. In that case you should check out Boost.Variant or Boost.Any .