草庐IT

c++ - 从模板中绑定(bind)模板函数

coder 2024-02-21 原文

接续 this question .我正在尝试绑定(bind)一个给定的函数,该函数返回除 void 之外的其他内容,以便稍后能够简单地调用 f() 。但是,以下代码无法在 GCC 4.4 上编译。它在 VS 2010 上编译,但生成的程序崩溃。

template<typename RetType>
void _hideRet(std::function<RetType ()> func, RetType * ret)
{
    *ret = func();
}

template<typename FuncType, typename RetType, typename ParamType>
std::function<void ()> registerFunc(FuncType func, RetType * ret, ParamType param)
{
    auto f = std::bind(func, std::forward<ParamType>(param));
    return std::bind(_hideRet<RetType>, f, ret);
}

int myFunction(std::string text)
{
    std::cout << text << std::endl;
    return 42;
}

int main()
{
    int ret = 0;
    auto f = registerFunc(myFunction, &ret, "text");
    f();
    std::cout << ret << std::endl;
    return 0;
}

GCC 产生了这个疯狂的消息:

In file included from /usr/include/c++/4.4/functional:70,
                 from func.cpp:4:
/usr/include/c++/4.4/tr1_impl/functional: In member function ‘typename std::result_of<_Functor(typename std::result_of<std::_Mu<_Bound_args, std::is_bind_expression::value, (std::is_placeholder::value > 0)>(_Bound_args, std::tuple<_UElements ...>)>::type ...)>::type std::_Bind<_Functor(_Bound_args ...)>::__call(const std::tuple<_UElements ...>&, std::_Index_tuple<_Indexes ...>) [with _Args = , int ..._Indexes = 0, 1, _Functor = void (*)(std::function<int()>, int*), _Bound_args = std::_Bind<int (*(const char*))(std::string)>, int*]’:
/usr/include/c++/4.4/tr1_impl/functional:1191:   instantiated from ‘typename std::result_of<_Functor(typename std::result_of<std::_Mu<_Bound_args, std::is_bind_expression::value, (std::is_placeholder::value > 0)>(_Bound_args, std::tuple<_UElements ...>)>::type ...)>::type std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args& ...) [with _Args = , _Functor = void (*)(std::function<int()>, int*), _Bound_args = std::_Bind<int (*(const char*))(std::string)>, int*]’
/usr/include/c++/4.4/tr1_impl/functional:1668:   instantiated from ‘static void std::_Function_handler<void(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Functor = std::_Bind<void (*(std::_Bind<int (*(const char*))(std::string)>, int*))(std::function<int()>, int*)>, _ArgTypes = ]’
/usr/include/c++/4.4/tr1_impl/functional:2005:   instantiated from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor, typename __gnu_cxx::__enable_if<(! std::is_integral::value), std::function<_Res(_ArgTypes ...)>::_Useless>::__type) [with _Functor = std::_Bind<void (*(std::_Bind<int (*(const char*))(std::string)>, int*))(std::function<int()>, int*)>, _Res = void, _ArgTypes = ]’
func.cpp:16:   instantiated from ‘std::function<void()> registerFunc(FuncType, RetType*, ParamType) [with FuncType = int (*)(std::string), RetType = int, ParamType = const char*]’
func.cpp:28:   instantiated from here
/usr/include/c++/4.4/tr1_impl/functional:1137: error: invalid conversion from ‘int’ to ‘std::_M_clear_type*’
/usr/include/c++/4.4/tr1_impl/functional:1137: error:   initializing argument 1 of ‘std::function<_Res(_ArgTypes ...)>::function(std::_M_clear_type*) [with _Res = int, _ArgTypes = ]’

我对内部 STL 工作原理的了解不足,无法从中做出任何东西。

但是在实验过程中我发现如果我删除第二个 std::bind从这样的 registerFunc 模板调用:

template<typename FuncType, typename RetType, typename ParamType>
std::function<RetType ()> registerFunc(FuncType func, RetType *, ParamType param)
{
    return std::bind(func, std::forward<ParamType>(param));
}

// in main
auto tmp = registerFunc(myFunction, &ret, "text");
auto f = std::bind(_hideRet<int>, tmp, &ret);
f();

代码在 VS 和 GCC 中都按预期工作。所以我的结论是问题出在调用std::bind(_hideRet<RetType>, ...)从模板函数中。问题是为什么这是个问题?更重要的是如何解决这个问题?

最佳答案

这绝对是惊人的,但是替换:

auto f = std::bind(func, std::forward<ParamType>(param));
return std::bind(_hideRet<RetType>, f, ret);

作者:

std::function<RetType ()> f = std::bind(func, std::forward<ParamType>(param));
return std::bind(_hideRet<RetType>, f, ret);

在 Visual Studio 2010 下按预期运行(这实际上是您将第二个 bind 移出 registerFunc 所做的)。我正在尝试理解它,但在那之前,这似乎是解决您的问题的方法,

关于c++ - 从模板中绑定(bind)模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4484306/

有关c++ - 从模板中绑定(bind)模板函数的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  3. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  4. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  5. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  6. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  7. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  8. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  9. ruby-on-rails - Mandrill API 模板 - 2

    我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h

  10. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

随机推荐