Boost :: Variant和function_types中:如何将函数放入Boost :: variant? [英] Boost::Variant and function_types in it: How to put functions into Boost::variant?

查看:519
本文介绍了Boost :: Variant和function_types中:如何将函数放入Boost :: variant?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

歌词:



我尝试通过MPI实现任务池。所以我需要某种RPC,但是在我的程序的不同部分之间工作,这意味着处理器A希望处理器B用参数D调用函数C.我们不能像进程线程一样传递指针到进程之间,所以我们需要一些包装容器来保存我们的函数指针在每个流程实例。所有内部一个源文件\ONE程序...所以我开始想知道如何在容器中存储具有不同签名的功能对象。我的API的想法当时是错误的 - 最好在池的构造中定义函数池中的所有函数(至少它会更容易实现)。但是在实现我遇到下一个麻烦:



问题:



function_types mpl :: vector variant ):

  #include< boost / function_types / function_type.hpp> 
#include< boost / mpl / vector.hpp>
#include< boost / mpl / vector_c.hpp>
#include< boost / variant.hpp>

#include< iostream>
#include< string>

template< class T>
int append(T val)
{
std :: cout< 你好;
return 0;
}

int main()
{
boost :: variant& boost :: function_types :: function_type< boost :: mpl :: vector< int,int> > :: type,boost :: function_types :: function_type< boost :: mpl :: vector< int,std :: string> > :: type>一个;
return 0;
}

不会编译落入:

 错误1错误C2066:转换为函数类型非法c:\program files\boost\include\boost\variant\variant.hpp 1231 1 

查看 source 我们看到:



此代码块:

  variant()
{
//注意用户:
//从这里编译错误表示第一个bound
// type不是默认构造的,因此variant不能
//支持自己的默认构造。
//
new(storage_.address())internal_T0();
indication_which(0); // zero是第一个有界类型的索引
}

所以我想知道:

 

include< boost / function_types / function_type.hpp>
#include< boost / mpl / vector.hpp>
#include< boost / mpl / vector_c.hpp>
#include< boost / variant.hpp>
#include< boost / function.hpp>

#include< iostream>
#include< string>

template< class T>
int append(T val)
{
std :: cout< 你好;
return 1;
}

int main()
{
boost :: variant< boost :: function< int(std :: string)>,boost :: function< int(int)> >一个;
a =& append< int> ;;

return 0;
}

其中失败:

 错误1错误C2668:'boost :: detail :: variant :: make_initializer_node :: apply< BaseIndexPair,Iterator> :: initializer_node :: initialize':对重载函数c :\program files\boost\include\boost\variant\variant.hpp 1330 



当然,我们可以使用共享指针来访问函数,如下所示:

  #include< boost / variant.hpp> 
#include< boost / shared_ptr.hpp>

#include< iostream>
#include< string>

模板< class in,class out>
struct s_append
{
out operator()(in val){
std :: cout< 你好;
return out();
}
};

int main()
{
boost :: variant< boost :: shared_ptr< s_append< int,int> >,boost :: shared_ptr< s_append< std :: string,int> > >一个;
boost :: shared_ptr< s_append< int,int> > b(new s_append< int,int>);
a = b;
return 0;
}

并且它会编译,但是结果API很糟糕 - 你必须1)创建函子为所有要使用的功能(意味着限制使用当前过程范围); 2)使用shared_pointers,所以我甚至不会真的得到如何调用函数嵌套的方式(简单的第一个猜测(* a)(22);

解决方案

尝试将虚拟类型插入正如您发现的注释,只有变体中的第一个类型用于变体自己的默认构造函数,你可以使用一个空的struct类型为此( struct NoFunction {}; )。



也就是说,使用boost ::函数作为变体中的类型...它们是默认可构造的至少。我不知道你从该方法的其他错误是由引起的,但只是想让你知道你可以如果你不能使用我提到的虚拟类型的解决方法,更追求那个角度。


Lyrics:

I try to implement a task pool over MPI. So I need some kind of RPC but one that would work between different parts of my program, meaning processor A wants processor B to call function C with argument D. We can not pass pointers to functions between processes like we do with threads, so we need some wrapper container to hold our function pointers at each process instance. All inside one source file\one program... So I started wondering about How to store functional objects with different signature in a container. My API Idea back then was wrong - it is better to define all functions in function pool at that pool construction (at least it shall be much easier to implement). But while implementing I faced next trouble:

Problem:

Such simple code (function_types, mpl::vector, variant):

#include <boost/function_types/function_type.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/variant.hpp>

#include <iostream>
#include <string>

template <class T>
int append(T val)
{
    std::cout << "hello";
    return 0;
}

int main()
{
    boost::variant<boost::function_types::function_type< boost::mpl::vector<int,int> >::type , boost::function_types::function_type< boost::mpl::vector<int,std::string> >::type  > a;
    return 0;
} 

Will not compile falling with:

Error   1   error C2066: cast to function type is illegal   c:\program files\boost\include\boost\variant\variant.hpp    1231    1

And looking at source we see:

this code block:

variant()
{
    // NOTE TO USER :
    // Compile error from here indicates that the first bound
    // type is not default-constructible, and so variant cannot
    // support its own default-construction.
    //
    new( storage_.address() ) internal_T0();
    indicate_which(0); // zero is the index of the first bounded type
}

So I wonder: How to get around this error?

Also I tried:

#include <boost/function_types/function_type.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/variant.hpp>
#include <boost/function.hpp>

#include <iostream>
#include <string>

template <class T>
int append(T val)
{
    std::cout << "hello";
    return 1;
}

int main()
{
    boost::variant< boost::function<int (std::string) >, boost::function<int (int) > > a;
    a= &append<int>;

    return 0;
}

Which fails with:

Error   1   error C2668: 'boost::detail::variant::make_initializer_node::apply<BaseIndexPair,Iterator>::initializer_node::initialize' : ambiguous call to overloaded function   c:\program files\boost\include\boost\variant\variant.hpp    1330

Any Ideas on how to make boost.variant hold functions?

Of course we can play with shared pointers to functors like so:

#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>

#include <iostream>
#include <string>

template <class in, class out>
struct s_append
{
    out operator()(in val) {
        std::cout << "hello";
        return out();
    }
};

int main()
{
    boost::variant<boost::shared_ptr<s_append<int, int> >, boost::shared_ptr< s_append<std::string, int> > > a;
    boost::shared_ptr<s_append<int, int> > b(new s_append<int, int> );
    a=b;
    return 0;
}

and it would compile but resulting API sucks - you have to 1) create functors for all functions you want to use (meaning limit there use of current process scope); 2) use shared_pointers and so I don't really even get how to call functions nested that way (simple first guess (*a)(22); just won't compile =( and API starts to be as bad as we would have using Boost.Any).

解决方案

Try inserting a dummy type as the first argument of the variant. As the comment you found explains, only the first type in the variant is used for the variant's own default constructor. You could use an empty struct type for this (struct NoFunction {};).

That said, you may have been onto something with the idea to use boost::functions as the types in the variant...they are default-constructible at least. I'm not sure what the other error you had from that approach was caused by, but just wanted to let you know you could pursue that angle more if you can't use the dummy-type workaround I mentioned.

这篇关于Boost :: Variant和function_types中:如何将函数放入Boost :: variant?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆