请指教,我如何解决以下问题 - 我希望有类成员变量boost :: variant类型,其类型来自已定义的mpl类型序列。之后,在main中,我想调用一个方法来调用顺序定义的每个类方法的方法。:)有点复杂,但让我说明一下:
struct worker1
{
void init()
{
std::cout << "Worker1 init called" << std::endl;
}
};
struct worker2
{
void init()
{
std::cout << "Worker2 init called" << std::endl;
}
};
typedef mpl::vector< worker1, worker2> workers;
template< typename U> struct process3
{
process3()
{
factory();
}
struct factoryrun
{
template< typename T > void operator()(T& x)
{
std::cout << "Factory entry" << std::endl;
std::cout << "Type is = " << typeid( T ).name() << std::endl;
m_t3.push_back( x ); // FAIL!!! :(( Doesn't work
}
};
struct runinit
{
template<typename T> void operator()(T& x)
{
x.init();
}
};
void init()
{
mpl::for_each<U>( runinit() );
}
void factory()
{
std::cout << "Factory start" << std::endl;
mpl::for_each<U>( factoryrun() );
}
typedef typename boost::make_variant_over< U >::type types; // FAIL!!! Doesn't work because I need to have variant<worker1, worker2> but not variant<workers>
static std::vector< boost::variant<types> > m_t;
};
template<typename K> std::vector< boost::variant<K> > process<K>::m_t;
int main() {
process<workers> prs;
// Here should be called init() for worker1 and worker2
prs.init();
return 0;
}
答案 0 :(得分:0)
问题解决了。这样的代码正在运作
typedef mpl::vector< worker1, worker2> workers;
template< typename U> struct process3
{
process3()
{
factory();
}
struct factoryrun
{
template< typename T > void operator()(T& x)
{
std::cout << "Factory entry" << std::endl;
std::cout << "Type is = " << typeid( T ).name() << std::endl;
m_t3.push_back( x );
}
};
struct runinit
{
template<typename T> void operator()(T& x)
{
x.init();
}
};
void init()
{
mpl::for_each<U>( runinit() );
}
void factory()
{
std::cout << "Factory start" << std::endl;
mpl::for_each<U>( factoryrun() );
}
typedef typename boost::make_variant_over< U >::type types;
typedef std::vector< boost::variant<types> > Vector; // Make typedef to simplify
static Vector m_t3;
};
template<typename U> typename process3<U>::Vector process3<U>::m_t3;
int main() {
process3<workers> prs3;
prs3.init();
return 0;
}
输出:
Factory start
Factory entry
Type is = 7worker1
Factory entry
Type is = 7worker2
Worker1 init called
Worker2 init called
答案 1 :(得分:0)
我很抱歉,但此代码的第一个版本不正确。对于init的每次调用,运行并停止新对象worker1和worker2的创建(每次构造函数os worker1和worker2被调用)。所以m_t3变量是没用的。
Bellow是正确的代码。正如您可能会看到worker1和worker2的构造函数被调用一次。
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//
struct worker1
{
worker1()
{
std::cout << "Worker1 ctor" << std::endl;
}
void init()
{
std::cout << "Worker1 init called. Object address [" << this << "]" << std::endl;
}
void run()
{
std::cout << "Worker1 run called. Object address [" << this << "]" << std::endl;
}
void stop()
{
std::cout << "Worker1 stop called. Object address [" << this << "]" << std::endl;
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//
struct worker2
{
worker2()
{
std::cout << "Worker2 ctor" << std::endl;
}
void init()
{
std::cout << "Worker2 init called. Object address [" << this << "]" << std::endl;
}
void run()
{
std::cout << "Worker2 run called. Object address [" << this << "]" << std::endl;
}
void stop()
{
std::cout << "Worker2 stop called. Object address [" << this << "]" << std::endl;
}
};
typedef mpl::vector< worker1, worker2 > workers;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//
template< typename U> struct process3
{
process3()
{
factory();
}
struct factoryrun
{
template< typename T > void operator()(T& x)
{
std::cout << "Factory entry" << std::endl;
std::cout << "Type is = " << typeid( T ).name() << std::endl;
m_t3.push_back( x );
}
};
void init()
{
static init_visitor vis;
std::for_each( m_t3.begin(), m_t3.end(), boost::apply_visitor( vis ) );
}
void run()
{
static run_visitor vis;
std::for_each( m_t3.begin(), m_t3.end(), boost::apply_visitor( vis ) );
}
void stop()
{
static stop_visitor vis;
std::for_each( m_t3.begin(), m_t3.end(), boost::apply_visitor( vis ) );
}
typedef typename boost::make_variant_over< U >::type types;
typedef std::vector<types> Vector; // Make typedef to simplify
static Vector m_t3;
struct init_visitor: public boost::static_visitor<>
{
template <typename T>
void operator()( T& x )
{
std::cout << "Init visitor type=" << typeid(x).name() << std::endl;
x.init();
}
};
struct run_visitor: public boost::static_visitor<>
{
template <typename T>
void operator()( T& x )
{
std::cout << "Run visitor type=" << typeid(x).name() << std::endl;
x.run();
}
};
struct stop_visitor: public boost::static_visitor<>
{
template <typename T>
void operator()( T& x )
{
std::cout << "Stop visitor type=" << typeid(x).name() << std::endl;
x.stop();
}
};
};
template<typename K> typename process3<K>::Vector process3<K>::m_t3;
int main() {
process3<workers> prs3;
prs3.init();
prs3.run();
prs3.stop();
return 0;
}
输出:
Factory start
Worker1 ctor
Factory entry
Type is = 7worker1
Worker2 ctor
Factory entry
Type is = 7worker2
Init visitor type=7worker1
Worker1 init called. Object address [0x21bf038]
Init visitor type=7worker2
Worker2 init called. Object address [0x21bf048]
Run visitor type=7worker1
Worker1 run called. Object address [0x21bf038]
Run visitor type=7worker2
Worker2 run called. Object address [0x21bf048]
Stop visitor type=7worker1
Worker1 stop called. Object address [0x21bf038]
Stop visitor type=7worker2
Worker2 stop called. Object address [0x21bf048]