【问题标题】:How can I pass a function as argument regardless of its return type in C++ ? (without using a template parameter for the passed function)无论 C++ 中的返回类型如何,如何将函数作为参数传递? (不使用传递函数的模板参数)
【发布时间】:2021-11-25 08:15:40
【问题描述】:

我正在尝试制作地图功能。 (回顾:映射函数是将函数应用于集合中的每个项目的函数)

这听起来很酷,但我希望我的 map 函数获得一个具有任何返回类型的函数作为参数。但是,我不想使用原生代码 sn-ps,例如 std::function

With std::function
请注意,即使使用 void 返回类型,它也适用于任何输入函数,无论其返回类型如何(我正在寻找的结果)

#include <functional>
using namespace std;

template <typename T>
void map(function<void(T&)> f, T * collection, unsigned length)
{
    for(unsigned i = 0; i < length; i++)
        f(collection[i]);
}

一种不适用于非 void 返回类型函数的方法

template <typename T>
void map(void (*f)(T&), T * collection, unsigned length)
{
    for(unsigned i = 0; i < length; i++)
        f(collection[i]);
}

我的解决方案

template <typename T, typename any>
void map(any (*f)(T&), T * collection, unsigned length)
{
    for(unsigned i = 0; i < length; i++)
        f(collection[i]);
}

您有不使用第二个模板参数的解决方案吗?
无论其实现如何,应该如何使用地图(示例):

#include "map.h"
#include <iostream>

void square(int& i){ i *= i; }

int main()
{
    int integers[] = { 5, 3, 2, 9 };

    map(&square, integers, 4);

    for(int i = 0; i < 4; i++)
        std::cout << integers[i] << std::endl;
    
    /*Output:
    25
     9
     4
    81
    */
}

【问题讨论】:

  • 我不关注。采用 2 个模板参数的解决方案到底有什么问题?
  • “但我认为这不是最好的方法。” -- 为什么不呢?您认为您的解决方案缺少哪些方面?
  • 你想对返回值做什么?
  • 如果您想要一个只有一个模板参数的解决方案,那么您应该在问题中指定它。 (您可能不喜欢该解决方案,但这是一个不同的问题)。该问题已作为骗子关闭,但它不正确(除非我弄错了,否则您不是在寻找可以满足您要求的 STL 函数,而是在尝试改进您自己编写的函数)。如果您编辑问题以准确地说明问题是什么,以及您的改进标准是什么,我会继续重新打开它。
  • 我认为如果没有额外的模板参数或与之等效的东西,您将无法做到。平台可能有调用约定,需要不同的代码来调用具有不同返回类型的函数。所以编译器必须在编译时知道f的返回类型,并且必须为每个返回类型实例化一个单独的函数。

标签: c++ function templates std-function


【解决方案1】:
#include <iostream>
#include <vector>
using namespace std;

void m(auto f, auto c)
{
   for(auto i : c)
      f(i);
}
 
int main() {
    m(
        [](int x) { cout << x << '\n'; },
        vector<int>{1, 2, 3});
    return 0;
}

你认为auto 是一个模板吗?您可以通过引用使c(和i)可变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    相关资源
    最近更新 更多