候选函数不可行:将 std::function 作为参数传递(C++)

问题描述 投票:0回答:1

我正在尝试使用 std::function 作为参数传递给另一个函数,但不断收到以下错误:

cannot resolve overloaded function 'returnValidsForHuman' based on conversion to type 'std::function<std::vector<std::pair<int, int> >(City<20, 20>&, std::pair<int, int>)>'
   64 |         coordinate_pairs valid_coordinates = findValidCoordinate(grid, organism.getPosition(), returnValidsForHuman);

main.cpp

#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <vector>
#include <tuple>
#include "../inc/City.h++"
#include "../inc/Organism.h++"
#include "../inc/Zombie.h++"
#include "../inc/Human.h++"

using std::cout, std::endl;

typedef std::vector<std::pair<int, int>> coordinate_pairs;
typedef std::pair<int, int> coordinate;

/** below are the methods used for actual functionality of the application */
template<typename T>
void updateGrid(T& grid, Organism& organism);

/** finds the valid coordinates an organism can move to */
template<typename T>
coordinate_pairs findValidCoordinate(T& grid, coordinate pos, std::function<coordinate_pairs(T&, coordinate)> _func);

/** returns the valid coordinates for Zombie */
template<typename T>
coordinate_pairs returnValidsForZombie(T& grid, coordinate coord);

/** returns the valid coordinates for Human */
template<typename T>
coordinate_pairs returnValidsForHuman(T& grid, coordinate coord);

int main() {
    /** main loop of the program */

    City grid = City<20, 20>();
    Zombie z1 = Zombie();

    updateGrid(grid, z1);

    return 0;
};

/** implementations */

template<typename T>
void updateGrid(T& grid, Organism& organism) {
    if(organism.toString() == "H") {
        coordinate_pairs valid_coordinates = findValidCoordinate(grid, organism.getPosition(), returnValidsForHuman);
    } else if(organism.toString() == "Z") {
        coordinate_pairs valid_coordinates = findValidCoordinate(grid, organism.getPosition(), returnValidsForZombie);
    }
};

/** find valid coordinates surrounding the organism */
template<typename T>
coordinate_pairs findValidCoordinate(T& grid, coordinate pos, std::function<coordinate_pairs(T&, coordinate)> _func) {
    return _func(grid, pos);
};

/** returns the valid coordinates for Zombie */
template<typename T>
coordinate_pairs returnValidsForZombie(T& grid, coordinate coord) {
    coordinate_pairs valids = coordinate_pairs();
};

/** returns the valid coordinates for Human */
template<typename T>
coordinate_pairs returnValidsForHuman(T& grid, coordinate coord) {

};

我不太确定问题出在哪里,想知道是否有人能够看到问题出在哪里?

背景:我正在为僵尸和人类类实现一个函数,我想将这些函数传递给

findValidCoordinate
函数以在二维网格(城市)中找到有效坐标。

c++ templates std-function
1个回答
0
投票

问题是你传递了一个函数模板

returnValidsForHuman
(分别为
returnValidsForZombie
)作为
std::function
参数。这是您的问题的一个更简单的示例:

#include <utility> //for std::pair
#include <vector>
#include <functional>

using coordinate = std::pair<int, int>;
using coordinate_pairs = std::vector<coordinate>;

template<typename T>
coordinate_pairs returnValidsForHuman(T& grid, coordinate coord);

template<typename T>
coordinate_pairs findValidCoordinate(T& grid, coordinate coord, std::function<coordinate_pairs(T&, coordinate)> _func);

struct City {};

int main()
{
    City grid;
    auto pos = coordinate{0, 0};
    coordinate_pairs valid_coordinates = findValidCoordinate(grid, pos, returnValidsForHuman); // OFFENDING LINE
}

gcc 12.2 的编译器错误:

<source>: In function 'int main()':
<source>:20:61: error: cannot resolve overloaded function 'returnValidsForHuman' based on conversion to type 'std::function<std::vector<std::pair<int, int> >(City&, std::pair<int, int>)>'
   20 |     coordinate_pairs valid_coordinates = findValidCoordinate(grid, pos, returnValidsForHuman);
      |             

https://godbolt.org/z/nsPeTxE65


要解决你的问题,你需要将主函数的最后一行(标有

// OFFENDING LINE
更改为

coordinate_pairs valid_coordinates = findValidCoordinate(grid, pos, returnValidsForHuman<City>);

这样你就可以通过正确的签名传递一个正确的函数模板实例化。

https://godbolt.org/z/Pr4fM44hP


作为旁注,您不必在这里使用

std::function
std::function
使用运行时多态性和类型擦除,以便您可以将同一签名的不同函数存储在一个连续的容器中。这不是必需的,它引入了不可忽略的运行时开销。相反,您可以为您的函数使用另一个模板参数,例如

template<typename T, typename F>
coordinate_pairs findValidCoordinate(T& grid, coordinate coord, F&& _func);

https://godbolt.org/z/jh7nnaMTT

© www.soinside.com 2019 - 2024. All rights reserved.