类型推断不适用于std :: function [英] Type deduction does not work with std::function

查看:183
本文介绍了类型推断不适用于std :: function的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下问题.当我尝试编译以下代码时

I have the following problem. When I try to compile the following code

template< typename T >
T func( T t)
{
  return t;
}

template< size_t N, typename T >
void foo( std::function< T(T) > func )
{
  // ...
}

int main()
{
  foo<3>( func<float> );

  return 0;
}

我得到了错误:

 no matching function for call to 'foo'
      foo<3>( func<float> );
      ^~~~~~
/Users/arirasch/WWU/dev/xcode/tests/tests/main.cpp:18:10: note: candidate template ignored: could not match 'function<type-parameter-0-1 (type-parameter-0-1)>' against 'float (*)(float)'
    void foo( std::function< T(T) > func )

但是,当我修复它时

template< typename T >
T func( T t)
{
  return t;
}

template< size_t N, typename T >
void foo( std::function< T(T) > func )
{
  // ...
}

int main()
{

  std::function< float(float) > input_func = func<float>;
  foo<3>( input_func );

  return 0;
}

即,当我将foo的输入函数显式声明为std::function< float(float) >时,编译就可以成功完成.

i.e., when I declare the input function of foo explicitly as std::function< float(float) >, the compilation can be done successfully.

有人知道我可以如何修正我的代码,以便我可以简单地编写类似于foo<3>( func<float> );(根据我的第一个代码示例)的内容,而不是

Does anyone know how I can fixe my code alternatively so that I can simply write something like foo<3>( func<float> ); (according to my first code example) instead of

std::function< float(float) > input_func = func<float>;
foo<3>( input_func );

必须明确说明input_func类型的地方?

where the type of input_func must be explicitly stated?

非常感谢.

推荐答案

类型推导在您的情况下不起作用,原因仅仅是无法推导.在大多数情况下,类型推导是与类型和其他模板参数的简单匹配.但是,C ++的某些暗角处理一些时髦的规则,但我不会在此回答.

Type deduction does not work in your case simply because it cannot be deduced. Type deduction is, in most cases, a simple match with types and other template parameters. There is however some dark corner of C++ that deal with deduction that has some funky rules, but I won't go into it for this answer.

这是一个示例,编译器可以推断出模板参数:

This is an example where the compiler can deduce template arguments:

template<typename T>
void test(std::vector<T>);

test(std::vector<int>{1, 2, 3, 4, 5, 6});

这对于编译器来说很容易.它需要std::vectorT.您给它一个std::vectorint. T必须为int.

This is easy for the compiler. It need a std::vector of T. You give it a std::vector of int. T must be int.

但是,在您的情况下,发生了很多事情:

However, in your case, There is a lot more stuff happening:

template<typename T>
void test(std::function<T(T)>);

int someFunc(int);

test(someFunc);

编译器无法进行匹配.自己尝试:给我一个T,它将使这两种类型相等:int(*)(int)std::function<T(T)>.确实,没有任何可能使这两种类型相同的T,而向量版本则很容易匹配.

The compiler can't do the match. Try for yourself: Give me a T that will make those two types equal: int(*)(int) to std::function<T(T)>. Indeed, there is no possible T that can make those two type to be the same, whereas the vector version was an easy match.

您会对我说:但是……指向函数的指针可以转换为std :: function,您真傻!"是的,确实可以兑换.但是在进行任何转换之前,编译器已经可以找到T是什么.如果不使用T,则将指针从函数转换为什么类?很多班?尝试匹配每个T吗?您的函数可以转换的可能性有多种.

You will say to me: "but... a pointer to a function is convertible to a std::function you silly!" Yeah, it is convertible, indeed. But before any conversion, the compiler has to find what T is. Without T, you make the conversion from a pointer to function to what class? Many class? Try to match every T? There is multiple possibility where your function would be convertible.

您如何进行这项工作?忘记std::function.只需接收T.

How can you make this work? Forget the std::function. Just receive T.

template<typename T>
T func(T t) {
  return t;
}

template<size_t N, typename T>
void foo(T func) {
  // ...
}

int main()
{
  foo<3>( func<float> );

  return 0;
}

请注意此示例的工作方式.您没有转换,没有std::function麻烦,可以与您可以想象的任何可调用对象一起工作!

Notice how this example works well. You have no conversion, no std::function thingy and can work with any callable you can possibly imagine!

您担心要接受任何类型吗?不用担心!参数类型是表达模板无论如何都可以对接收到的参数进行处理的一种不好的方法.您应该使用 expression 对其进行限制.该表达式将告诉其他人您将如何使用T以及需要什么接口T.顺便说一句,我们称那为sfinae:

Are you worried about accepting any type? No worry here! Parameter types are a bad way to express what a template can do with received parameters anyway. You should restrict it with an expression. That expression will tell others how you will use T and what interface T need to have. btw, we call that sfinae:

template<size_t N, typename T>
auto foo(T func) -> decltype(void(func(std::declval<int>()))) {
  // ...
}

在此示例中,您限制了func可以被int调用,并且仍然返回void.

In this example, you restrict func to be callable with a int and still return void.

这篇关于类型推断不适用于std :: function的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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