Search code examples
c++c++11default-valuestd-function

Initialization of anonymous class member variable with std::function


I wonder if there is a workaround is such situation:

class A
{
    class
    {
    public:
        void setValue(int val) {i=val;}
    private:
        int i;
    } B = initB(10);

    std::function<decltype(B)(int)> initB = [this](int value)
                                            {decltype(B) temp;
                                             temp.setValue(value);
                                             return temp;};
}


//...
    A a; //crash
//...

I suppose it is caused by order of initialization. Variable B is initilized by calling an uninitilized std::function instance, hence the crash. By my logic, the workaround would be to initialize std::function first, then initialize member B. But then, such code is not valid:

class A
    {
        //error: 'B' was not declared in this scope
        std::function<decltype(B)(int)> initB = [this](int value)
                                                {decltype(B) temp;
                                                 temp.setValue(value);
                                                 return temp;};
        class
        {
        public:
            void setValue(int val) {i=val;}
        private:
            int i;
        } B = initB(10);
    }

I tried to make to make the std::function static, and such code works, but requires non-constexpr/const member, because std::function has non-trivial destructor - which is bad, because that requires source file, which requires creating such file, which requires some efford and destruction of my beautiful header-only class hierarchy! (I mean, I could be lazy and define this variable in the header, but then the multiple definition problem occurs). I know it might be a bad design (i'm just testing things out), but do you have any ideas how the problem can be solved without involving source files?


Solution

  • Although your example is contrived, there are times when I've needed (or its more convenient) to initialize complex objects in a similar way.

    But, why use std::function<>? Why not just use a function?

    class A
    {
        class
        {
        public:
            void setValue(int val) { i = val; }
        private:
            int i;
        } B = initB(10);
    
        static decltype(B) initB(int value)
        {
            decltype(B) temp;
            temp.setValue(value);
            return temp; 
        }
    };
    

    Although, I wouldn't normally use decltype(B); I would just give the class a name.