Is it possible to have an “auto” member variable?

后端 未结 4 1566
别跟我提以往
别跟我提以往 2021-01-03 20:54

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

相关标签:
4条回答
  • 2021-01-03 20:58

    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.

    0 讨论(0)
  • 2021-01-03 21:21

    Indirectly, provided that you don't reference a member of the class.

    This can also now be achieved through deduction guides, these were introduced in C++17 and have recently (finally) support in VC++ has been added (clang and GCC already had it).

    https://en.cppreference.com/w/cpp/language/class_template_argument_deduction

    For example:

    template <typename>
    struct CString;
    
    template <typename T, unsigned N>
    struct CString<std::array<T, N>>
    {
        std::array<T, N> const Label;
    
        CString(std::array<T, N> const & pInput) : Label(pInput) {}
    };
    
    template <typename T, std::size_t N>
    CString(std::array<T, N> const & pInput) -> CString<std::array<T, N>>;
    

    https://godbolt.org/z/LyL7UW

    This can be used to deduce class member types in a similar manner to auto. Although the member variables need to be Dependant somehow on the constructor arguments.

    0 讨论(0)
  • 2021-01-03 21:23

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

    struct Timer {
        static const auto start = 0;
    };
    

    A working example in Coliru.

    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<typename T>
    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<typename T>
    Timer<typename std::decay<T>::type> MakeTimer(T&& startVal) {   // Forwards the parameter
       return Timer<typename std::decay<T>::type>{std::forward<T>(startVal)};
    }
    

    Live example.

    0 讨论(0)
  • 2021-01-03 21:25

    No. Each constructor could have its own initializer for start, so there could be no consistent type to use.

    If you do have a usable expression, you can use that:

    struct Timer {
    
       Foo getAFoo();
    
       delctype(Timer().getAFoo().Bar()) start;
    
       Timer() : start(getAFoo().Bar()) { /***/ }
    };
    
    0 讨论(0)
提交回复
热议问题