MPL replace without casting container to merge

I have this 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;
    }
};

it uses CRTP to allow the HaveChildren class to access its child member variable.

The type childListType is a class that inherits from boost :: fusion :: vector.

I would like to programmatically make the member variable children contain one space between each line.

So if I enter:

<string,string>

children become:

<string, space,string>

If I enter:

<string,string,string>

he becomes

<string,space,string,space,string>

and etc.

I use boost-fusion, so it should be at compile time.

I tried to do it like this:

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;
    }
};

But then MPL: replace changes the type of container from my own class, which inherits from boost :: fusion :: vector, to boost :: fusion :: vector4, and this destroys my streaming overloads.

You may notice that instead <string,space>I replace each line with stringAndSpace.

<string,space>, , .

, :

typedef boost::mpl::replace< context, string, stringAndSpace >::type replacedContext;

- , ,

struct childrenListType : public  boost::fusion::vector<CHILDREN_TYPES...>

I?

: http://ideone.com/XxYTOt

typeinfo , mpl children: 16childrenListTypeIISsSsSsSsEE

: N5boost6fusion7vector4I14stringAndSpaceS2_S2_S2_EE

, , :

(this  sentence  needs  spaces )
+4
1

++ 14 - , , ? ++ 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).

+2

All Articles