MPL替换而不铸造聚变容器
MPL replace without casting the fusion container
我有这个class
struct MyChildrenNeedsSpace : HaveChildren<MyChildrenNeedsSpace>
{
typedef childrenListType<string, string, string, string> context;
const context children;
MyChildrenNeedsSpace() : children("this", "sentence", "needs", "spaces")
{
std::cout << endl << "The children type is:" << endl << typeid(children).name() << endl;
}
};
它使用 CRTP 允许 HaveChildren class 访问其 children 成员变量。
childrenListType 是继承自 boost::fusion::vector 的 class。
我想以编程方式使 children 成员变量在每个字符串之间包含一个 space class。
所以如果我输入:
<string,string>
children 变为:
<string, space,string>
如果我输入:
<string,string,string>
变成
<string,space,string,space,string>
等等
我正在使用 boost fusion,所以它必须在编译时。
我试过这样做:
struct MyChildrenNeedsSpaceWithReplacer : HaveChildren<MyChildrenNeedsSpaceWithReplacer>
{
typedef childrenListType<string, string, string, string> context;
typedef boost::mpl::replace< context, string, stringAndSpace >::type replacedContext;
const replacedContext children;
MyChildrenNeedsSpaceWithReplacer() : children( "this" ,"sentence" , "needs" , "spaces")
{
std::cout << endl << "The children type is:" << endl <<typeid(children).name() << endl;
}
};
但是 MPL:replace 将容器类型从我自己的 class 更改为 boost::fusion::vector4,这会破坏我的流式传输超载者。
您可能会注意到,我没有使用 <string,space>
,而是将每个字符串替换为 stringAndSpace
。
有 <string,space>
会是最好的,但其他方式对我来说更容易。
总而言之:
typedef boost::mpl::replace< context, string, stringAndSpace >::type replacedContext;
转换我的容器类型 - 你能帮忙制作一个函数,在编译时定义一个类型如下 class
struct childrenListType : public boost::fusion::vector<CHILDREN_TYPES...>
我输入的每个字符串之间有一个 space 的模板参数?
我已将完整的源代码发布在:http://ideone.com/XxYTOt
他们的编译器类型信息说没有 mpl 替换 children 类型是:16childrenListTypeIISsSsSsSsEE
并与:N5boost6fusion7vector4I14stringAndSpaceS2_S2_S2_EE
您还可以看到流重载失败,因为它输出括号:
(this sentence needs spaces )
对于 C++14,我在这里看不到提升的必要性——或者我可能遗漏了您的一个要求?以下将在普通 C++14 的类型之间添加空格:
struct space {};
template<typename, typename=void> struct spacer;
template<template<typename...> class T>
struct spacer<T<>> { using type = T<>; };
template<template<typename...> class T,typename T1, typename... Ts>
struct spacer<T<T1,Ts...>>
: spacer<T<T1,Ts...>, std::make_index_sequence<2*sizeof...(Ts)+1>> {};
template<template<typename...> class T,typename... Ts, std::size_t... Ns>
struct spacer<T<Ts...>, std::index_sequence<Ns...>>
{
using tuple = std::tuple<Ts...>;
using type =
T<std::conditional_t<(Ns%2)==0,std::tuple_element_t<Ns/2,tuple>,space>...>;
};
template<typename T> using spacer_t = typename spacer<T>::type;
上面保留了你的外部容器类型,所以在你的情况下,如果你传入一个 boost::fusion::vector<...>
,这也是你将得到的结果(只是有额外的 space
s) .
我有这个class
struct MyChildrenNeedsSpace : HaveChildren<MyChildrenNeedsSpace>
{
typedef childrenListType<string, string, string, string> context;
const context children;
MyChildrenNeedsSpace() : children("this", "sentence", "needs", "spaces")
{
std::cout << endl << "The children type is:" << endl << typeid(children).name() << endl;
}
};
它使用 CRTP 允许 HaveChildren class 访问其 children 成员变量。
childrenListType 是继承自 boost::fusion::vector 的 class。
我想以编程方式使 children 成员变量在每个字符串之间包含一个 space class。
所以如果我输入:
<string,string>
children 变为:
<string, space,string>
如果我输入:
<string,string,string>
变成
<string,space,string,space,string>
等等
我正在使用 boost fusion,所以它必须在编译时。
我试过这样做:
struct MyChildrenNeedsSpaceWithReplacer : HaveChildren<MyChildrenNeedsSpaceWithReplacer>
{
typedef childrenListType<string, string, string, string> context;
typedef boost::mpl::replace< context, string, stringAndSpace >::type replacedContext;
const replacedContext children;
MyChildrenNeedsSpaceWithReplacer() : children( "this" ,"sentence" , "needs" , "spaces")
{
std::cout << endl << "The children type is:" << endl <<typeid(children).name() << endl;
}
};
但是 MPL:replace 将容器类型从我自己的 class 更改为 boost::fusion::vector4,这会破坏我的流式传输超载者。
您可能会注意到,我没有使用 <string,space>
,而是将每个字符串替换为 stringAndSpace
。
有 <string,space>
会是最好的,但其他方式对我来说更容易。
总而言之:
typedef boost::mpl::replace< context, string, stringAndSpace >::type replacedContext;
转换我的容器类型 - 你能帮忙制作一个函数,在编译时定义一个类型如下 class
struct childrenListType : public boost::fusion::vector<CHILDREN_TYPES...>
我输入的每个字符串之间有一个 space 的模板参数?
我已将完整的源代码发布在:http://ideone.com/XxYTOt
他们的编译器类型信息说没有 mpl 替换 children 类型是:16childrenListTypeIISsSsSsSsEE
并与:N5boost6fusion7vector4I14stringAndSpaceS2_S2_S2_EE
您还可以看到流重载失败,因为它输出括号:
(this sentence needs spaces )
对于 C++14,我在这里看不到提升的必要性——或者我可能遗漏了您的一个要求?以下将在普通 C++14 的类型之间添加空格:
struct space {};
template<typename, typename=void> struct spacer;
template<template<typename...> class T>
struct spacer<T<>> { using type = T<>; };
template<template<typename...> class T,typename T1, typename... Ts>
struct spacer<T<T1,Ts...>>
: spacer<T<T1,Ts...>, std::make_index_sequence<2*sizeof...(Ts)+1>> {};
template<template<typename...> class T,typename... Ts, std::size_t... Ns>
struct spacer<T<Ts...>, std::index_sequence<Ns...>>
{
using tuple = std::tuple<Ts...>;
using type =
T<std::conditional_t<(Ns%2)==0,std::tuple_element_t<Ns/2,tuple>,space>...>;
};
template<typename T> using spacer_t = typename spacer<T>::type;
上面保留了你的外部容器类型,所以在你的情况下,如果你传入一个 boost::fusion::vector<...>
,这也是你将得到的结果(只是有额外的 space
s) .