从函子模板参数(MSVC特定)中减去可变参数和返回类型 [英] Deduce variadic args and return type from functor template parameter (MSVC-specific)

查看:184
本文介绍了从函子模板参数(MSVC特定)中减去可变参数和返回类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面代码中的函数 invoke 是调用另一个函数/ functor / lambda的简单包装,使得 invoke(f,args。 ..) equals f(args ...)。 (这个的原因是成员函数也有重载,允许两种用法的通用语法。)



这个实现在g ++中起作用:

  template< class Fn,class ... Args> 
auto invoke(Fn f,Args ... args) - > decltype(f(args ...)){
return f(args ...);
}

int y = invoke([](int x){return x + 1;},42); // y = 43

演示



但是,MSVC 2012(11月CTP)抱怨:



< =lang-none prettyprint-override> 错误:C2893:无法专门化函数模板'unknown-type invoke(Fn,Args ...)'
使用以下模板参数:
'main ::< lambda_687537b292ffb7afcfd8f8fc292d6e73>'
'int'

错误消息中的 int 来自传递给 invoke 42 c $ c>,而不是lambda的参数。我通过传递不同于 invoke 的东西来检查这个。)



我如何解决这个问题与MSVC 2012(11月CTP)?



我试过的东西:




  • 当我将可变参数模板参数更改为单个参数(但仍然是模板参数,即在上面的代码中删除所有 ... ),代码编译。但是我需要支持任何数量的参数。


  • 如果我用非泛型 int 返回类型。但是显然我想支持通用返回类型。


  • 如果我传递一个函数指针而不是一个lambda,行为不会改变。所以它不与lambdas相关。示例错误消息:

     错误:C2893:无法专门化函数模板未知类型invoke Fn,Args ...)'
    使用以下模板参数:
    'int(__cdecl *)(int)'
    'double'



解决方案

尝试使用 typename result_of< ; F(Args ...)> :: type 。 (我的意思是:使用类型不是值)。



这不支持SFINAE在标准下,但如果可能工作在一半兼容的C ++ 11编译器



还可以使用 Args&& ... ,如果你的编译器没有爆炸, / p>

The function invoke in the following code is a simple wrapper for invoking another function / functor / lambda, such that invoke(f,args...) equals f(args...). (The reason behind this is to also have overloads for member functions, allowing a generalized syntax for both usages.)

This implementation works in g++:

template <class Fn, class ...Args>
auto invoke(Fn f, Args ...args) -> decltype(f(args...)) {
    return f(args...);
}

int y = invoke([](int x){ return x+1; }, 42);   // y = 43

Demo

However, MSVC 2012 (Nov CTP) complains:

Error: C2893: Failed to specialize function template 'unknown-type invoke(Fn,Args...)'
With the following template arguments:
'main::<lambda_687537b292ffb7afcfd8f8fc292d6e73>'
'int'

(Note that the int in the error message comes from the 42 being passed to invoke, not from the lambda's argument. I checked this by passing something different to invoke.)

How can I fix this to work with MSVC 2012 (Nov CTP)?

Things I tried:

  • When I change the variadic template arguments to a single argument (but still a template argument, i.e. remove all ... in the code above), the code compiles. But I need to Support any number of arguments.

  • It also compiles if I replace the trailing return type with a non-generic int return type. But obviously I want to support generic return types.

  • The behavior doesn't change if I pass a function pointer instead of a lambda. So it isn't related to lambdas. Example error message:

    Error: C2893: Failed to specialize function template 'unknown-type invoke(Fn,Args...)'
    With the following template arguments:
    'int (__cdecl *)(int)'
    'double'
    

解决方案

Try using typename result_of<F(Args...)>::type. (and I do mean the case: use types not values).

This does not support SFINAE under the standard, but if might work in half compliant C++11 compilers.

Also use Args&&... and perfect forward if your compiler does not blow up.

这篇关于从函子模板参数(MSVC特定)中减去可变参数和返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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