0

When declaring and defining a struct with a static member of the same type, i cannot seem to figure out how to define the value.

I have a struct containing two strings. I want there to be a defined/constant version I can access from the type itself. To do this I am declaring static members in a header and trying to define them in the class.

Header:

//.h
#pragma once
#include "BaseStruct.h"
#include<string>

namespace A {
    namespace B{
        struct MyStruct : A::C::BaseStruct
        {
            MyStruct(std::string s1, std::string s2);
            static MyStruct myStaticStruct;
        };
    }
}

Class:

//.cpp
#include "BaseStruct.h"
#include "MyStruct.h"

namespace A {
    namespace B {
        struct MyStruct : A::C::BaseStruct
        {
            MyStruct(std::string s1, std::string s2) : BaseStruct(s1, s2)
            {}
        };        

// I have been trying to define MyStaticStruct here.

    }
}

How do I define the static member declared in the header? I can't access the static member using:

MyStruct::MyStaticStruct

but I have to use:

A::B::MyStruct::MyStaticStruct

Why can't I access the static member even though I am inside the A::B namespace? And of course, how do I define a value for that member?

ChrisM
  • 45
  • 7
  • Can you please try to create a [mcve] to show us, and include the full set of errors you might get? – Some programmer dude Mar 05 '20 at 14:31
  • It sounds like your looking for the singleton pattern https://stackoverflow.com/q/1008019/942596. Are you attempting to restrict that class to only one instance in your program? – andre Mar 05 '20 at 14:41

2 Answers2

2

You shouldn't redeclare your class in your cpp files, just define your methods and static members:

namespace A {
    namespace B {
            MyStruct::MyStruct(std::string s1, std::string s2) : BaseStruct(s1, s2)
            {}

            MyStruct MyStruct::myStaticStruct("s1", "s2");
    }
}

Note that you may rapidly run into the static initialisation order fiasco with this approach. A better option is to use a function to retrieve your singleton:

#include<string>

namespace A {
    namespace C{
        struct BaseStruct{
            BaseStruct(std::string s1, std::string s2) {};
        };
    }
    namespace B{
        struct MyStruct : A::C::BaseStruct
        {
            MyStruct(std::string s1, std::string s2);
            static MyStruct& myStaticStruct();
        };
    }
}

namespace A {
    namespace B {
            MyStruct::MyStruct(std::string s1, std::string s2) : BaseStruct(s1, s2)
            {}

            MyStruct& MyStruct::myStaticStruct()
            {
                static MyStruct singleton("s1", "s2");
                return singleton;
            }
    }
}

The singleton is lazily initialised the first time you call myStaticStruct()

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
1

Remove the class definition from the .cpp file and only implement the member functions there - and initialize your static variables:

.cpp

namespace A {
    namespace B {
        // member functions
        MyStruct::MyStruct(std::string s1, std::string s2) : BaseStruct(s1, s2) {}

        // static variables
        MyStruct MyStruct::myStaticStruct("foo", "bar");
    }
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108