c++

So I tried yesterday to start using std::initializer_list but that wasn't a huge success. There is one of my last try:

#include <unordered_map>
#include <string>

     struct XmlState {

        using U_StateFunc = std::function<void()>;
        using U_MapStateFunc = std::unordered_map<std::string, U_StateFunc>;

        U_StateFunc     beforeProcess;
        U_StateFunc     afterProcess;
        U_MapStateFunc  funcMap;

        XmlState
          (U_StateFunc&& bProcess,
           U_StateFunc&& aProcess,
           std::initializer_list<typename U_MapStateFunc::value_type> mapParams)
          : beforeProcess(std::move(bProcess)),
            afterProcess(std::move(aProcess)),
            funcMap(mapParams)
        {}
      };

      template < size_t NB_STATES >
      class XmlParser {

        using U_StateArray = std::array<XmlState, NB_STATES>;
        U_StateArray  m_states;

        public:
          XmlParser
            (std::initializer_list<typename U_StateArray::value_type> states)
            : m_states{states}
          {}

      };

      XmlParser<1>  test {
      {
        {
            XmlState::U_StateFunc(), XmlState::U_StateFunc(),
            {
              { "Tag1", []() {} },
              { "Tag2", []() {} },
              { "Tag3", []() {} }
            }
        }
      }};

int main() {}

Wandbox

I'm wondering why I struggle so much to use this. {} this is a std::initializer_list empty, and {{}} this is one with one element right? But you need to put them inside the constructor like Foo({{}}) ? Or using another list Foo{{{}}} . I mean, this looks simple, but I just can't make it happen.

Btw I'd like to know if it's better to use initializer_list or template parameter pack? Both with move semantic, because there is no temporary object with parameter pack after all?


Not sure if this is what you are looking for, but if you change XmlParser to take a U_StateArray in the constructor, you can make the syntax close to your original.

//Changed constructor in XmlParser
XmlParser (U_StateArray states) : m_states{states} {}

//Used like this
XmlParser<2>  test {{

        XmlState(XmlState::U_StateFunc(), XmlState::U_StateFunc(),
        {
          { "Tag1", []() {} },
          { "Tag2", []() {} },
          { "Tag3", []() {} }
        }),

        XmlState(XmlState::U_StateFunc(), XmlState::U_StateFunc(),
        {
          { "Tag4", []() {} },
          { "Tag5", []() {} }
        })

}};

Another option is to change the std::array to a std::vector . Then your code works since std::vector has a constructor for std::initializer_list .

A third option is to make a helper, that takes an std::initializer_list and returns an appropriate std::array . Like suggested here.

链接地址: http://www.djcxy.com/p/83740.html

上一篇: Python:获取WindowsError而不是IOError

下一篇: C ++