能否在我们的自定义类中像std::function一样使用模板类型

huangapple go评论63阅读模式
英文:

Can we take template types like the std::function does in our custom classes

问题

我正在学习一些基本的C++,发现我们可以将lambda函数传递给接受std::function的函数,就像下面这样:

int someFunction(std::function<int(int, int)> sum) {
  return sum(1, 3);
}

我对std::function如何接受模板类型"int(int, int)"感到困惑,通常我只见过类接受类型,类似于someClass<int, int>

我们如何定义接受模板类型"int(int, int)"的类?

我尝试过声明类如下:

template<typename A(typename B)> // --> 这只会导致语法错误。
class SomeClass {};
英文:

I was learning some basic cpp and I found out that we can pass lambda functions to a function accepting a std::function like below:

int someFunction(std::function&lt;int(int, int)&gt; sum) {
  return sum(1,3);
}

I was confused as to how the std::function is taking template types as "int(int, int)" generally I have only see classes taking types like someClass<int, int>.

How do we define classes that take the template types like "int(int, int)"?

I tried declaring classes like

template&lt;typename A(typename B)&gt; // --&gt; this just gives an syntax error.
class SomeClass {};

答案1

得分: 0

初始时,你的例子不能编译。

// 返回类型是 int,参数是一个返回 int 的函数
int someFunction(std::function<int(int)> sum) {
  return sum(1, 3);
}

/*
std::function<int(int)>
              ^    ^
              |    |
           返回类型 参数类型  

因此,调用 sum(1, 3) 将需要 function<int(int, int)>,因为你传递了两个参数并返回一个值。
*/

更多例子

/*
结构是 "return_type(param1, param2, ..)" 用于函数,以下的 `[]` 用于变量捕获(按值 [x] 或按引用 [&x])在函数外部。
*/

// 接受一个参数并且不返回任何东西
std::function<void(int)> print = [](auto i) {
   std::cout << i << std::endl;
}

// 接受两个参数并返回它们的和
std::function<int(int, int)> sum = [](auto i, auto j) {
   return i + j;
}

// 接受一个参数并返回加 2 后的值
std::function<int(int)> sum = [](auto i) {
   return i + 2;
}

我们如何定义接受类似 "int(int, int)" 这样的模板类型的类?

template<typename T>
class Class {
  public:
    void call(T sum) {
      std::cout << sum(1, 3) << std::endl;
    } 
};

// 用法
auto sum = [](auto a, auto b) { return a + b; };
auto instance = new Class<decltype(sum)>();
instance->call(sum);
英文:

At first, your example should not compile.

int someFunction(std::function&lt;int(int)&gt; sum) {
  return sum(1,3);
}

/*
std::function&lt;int(int)&gt;
              ^    ^
              |    |
           return  parameter
            type  

So, calling sum(1,3) would require function&lt;int(int, int) as you are passing two parameters and returning a value.
*/

More examples

/*
The structure is &quot;return_type(param1, param2, ..)&quot; for the function and the following 
`[]` is used for variable capture (by value [x] or by reference [&amp;x]) that resides out the function.
*/

// takes one param and returns nothing
function&lt;void(int)&gt; print = [](auto i) {
   court&lt;&lt;i&lt;&lt;endl;
}

// takes two params and returns the sum
function&lt;int(int, int)&gt; sum = [](auto i, auto j) {
   return i + j;
}

// takes one param and returns with added 2
function&lt;int(int)&gt; sum = [](auto i) {
   return i + 2;
}

> How do we define classes that take the template types like "int(int, int)"?

template&lt;typename T&gt;
class Class {
  public:
    void call(T sum) {
      cout &lt;&lt; sum(1, 3) &lt;&lt; endl;
    } 
};

// usage
auto sum = [](auto a, auto b) { return a + b; };
auto instance = new Class&lt;decltype(sum)&gt;();
instance-&gt;call(sum);

答案2

得分: 0

I am answering my own question thanks to the comment by @Raildex. Basically the type int(int, int) in the question would refer to a function pointer that takes 2 ints and returns an int.

So an example class could just be:

template<typename T>
class SomeClass {
  public:
    void someMethod(T sum) {
      cout << sum(1, 3) << endl;
    } 
};

SomeClass someClass;
// the template type is not required here, but has been added just for clarity.
someClass.someMethod<int(int, int)>([](int a, int b){return a + b;});
英文:

I am answering my own question thanks to the comment by @Raildex. Basically the type int(int, int) in the question would refer to a function pointer that takes 2 ints and returns an int.

So an example class could just be:

template&lt;typename T&gt;
class SomeClass {
  public:
    void someMethod(T sum) {
      cout &lt;&lt; sum(1, 3) &lt;&lt; endl;
    } 
};

SomeClass someClass;
// the template type is not required here, but has been added just for clarity.
someClass.someMethod&lt;int(int, int)&gt;([](int a, int b){return a + b;});

huangapple
  • 本文由 发表于 2023年3月12日 14:26:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75711405.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定