搞乱 initializer_list
Messing with initializer_list
所以我昨天尝试开始使用 std::initializer_list,但这并不是一个巨大的成功。这是我最后的尝试之一:
#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() {}
我想知道为什么我这么费力地使用它。 {}
这是一个 std::initializer_list
空的,{{}}
这是一个只有一个元素的对吗?但是你需要像 Foo({{}})
这样把它们放在构造函数中吗?或者使用另一个列表 Foo{{{}}}
。我的意思是,这看起来很简单,但我就是做不到。
顺便说一句,我想知道使用initializer_list 还是模板参数包更好?都带move语义,因为毕竟没有带参数pack的临时对象?
不确定这是否是您要查找的内容,但如果您将 XmlParser
更改为在构造函数中采用 U_StateArray
,则可以使语法接近原始语法。
//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", []() {} }
})
}};
另一种选择是将 std::array
更改为 std::vector
。那么你的代码就可以工作了,因为 std::vector
有一个 std::initializer_list
.
的构造函数
第三种选择是制作一个助手,它需要一个 std::initializer_list
和 returns 一个合适的 std::array
。喜欢建议 .
所以我昨天尝试开始使用 std::initializer_list,但这并不是一个巨大的成功。这是我最后的尝试之一:
#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() {}
我想知道为什么我这么费力地使用它。 {}
这是一个 std::initializer_list
空的,{{}}
这是一个只有一个元素的对吗?但是你需要像 Foo({{}})
这样把它们放在构造函数中吗?或者使用另一个列表 Foo{{{}}}
。我的意思是,这看起来很简单,但我就是做不到。
顺便说一句,我想知道使用initializer_list 还是模板参数包更好?都带move语义,因为毕竟没有带参数pack的临时对象?
不确定这是否是您要查找的内容,但如果您将 XmlParser
更改为在构造函数中采用 U_StateArray
,则可以使语法接近原始语法。
//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", []() {} }
})
}};
另一种选择是将 std::array
更改为 std::vector
。那么你的代码就可以工作了,因为 std::vector
有一个 std::initializer_list
.
第三种选择是制作一个助手,它需要一个 std::initializer_list
和 returns 一个合适的 std::array
。喜欢建议