【问题标题】:What is this error? "no matching function for call to 'foreach(std::array<int, 4>&, void(&)(int))"这是什么错误? “没有匹配函数调用'foreach(std::array<int, 4>&, void(&)(int))”
【发布时间】:2021-04-19 23:44:47
【问题描述】:

我创建了一个foreach() 函数,它应该打印数组的值,但它告诉我:

没有匹配函数调用'foreach(std::array&, void(&)(int))'

还有:

不匹配的类型'unsigned int'和'long unsigned int'

但是当我尝试使用vectors 代替数组,或者在第11 行使用template&lt;unsigned int N&gt; 代替unsigned int 时,如果我使用long unsigned int,它工作正常。

那么,为什么我需要使用long unsigned int

数组的“无匹配函数”错误是什么意思?

#include<iostream>
#include<string>
#include<array>

typedef void(*func)(int);

void print(int value) {
    std::cout << "value is : " << value << std::endl;
}

template<unsigned int N>
void foreach(std::array<int, N>& values, func print) {
    int value;
    for(int i = 0; i < values.size(); i++) {
        value = values[i];
        print(value);
    }
}

int main() {

    std::array<int, 4> arr = { 0, 1, 2, 3 };
    foreach(arr, print);

    return 0;
}

使用向量:

#include<iostream>
#include<string>
#include<vector>

typedef void(*func)(int);

void print(int value) {
    std::cout << "value is : " << value << std::endl;
}

void foreach(std::vector<int>& values, func print) {
    int value;
    for(int i = 0; i < values.size(); i++) {
        value = values[i];
        print(value);
    }
}

int main() {

    std::vector<int> v = { 0, 1, 2, 3 };
    foreach(v, print);

    return 0;
}

【问题讨论】:

  • std::for_each() 有什么问题?如果是一对迭代器,为什么不直接包装呢?
  • template&lt;size_t N&gt; 似乎更适合void foreach

标签: c++ arrays vector stl


【解决方案1】:

std::array 的模板不采用unsigned int,它采用std::size_t,它可能会或可能不会(可能不会)定义为unsigned int

template<size_t N>
void foreach(std::array<int, N>& values, func print);

一个更好的选择是通过传递迭代器而不是实际的容器,让你的函数与容器无关,例如:

#include <iostream>
#include <string>
#include <array>
#include <vector>

typedef void(*func)(int);

void print(int value) {
    std::cout << "value is : " << value << std::endl;
}

template<typename Iter>
void foreach(Iter begin, Iter end, func print) {
    while (begin != end) {
        print(*begin);
        ++begin;
    }
}

int main() {

    std::array<int, 4> arr = { 0, 1, 2, 3 };
    foreach(arr.begin(), arr.end(), print);

    std::vector<int> v = { 0, 1, 2, 3 };
    foreach(v.begin(), v.end(), print);

    return 0;
}

如果您将print 参数也更改为模板,这不仅允许该函数与多个容器一起使用,而且还可以与不同的元素类型一起使用,例如:

#include <iostream>
#include <string>
#include <array>
#include <vector>

void printInt(int value) {
    std::cout << "value is : " << value << std::endl;
}

void printStr(const std::string &value) {
    std::cout << "value is : " << value << std::endl;
}

template<typename Iter, typename Callable>
void foreach(Iter begin, Iter end, Callable print) {
    while (begin != end) {
        print(*begin);
        ++begin;
    }
}

int main() {

    std::array<int, 4> arr = { 0, 1, 2, 3 };
    foreach(arr.begin(), arr.end(), printInt);

    std::vector<std::string> v = { "hello", "world", "joe", "smoe" };
    foreach(v.begin(), v.end(), printStr);

    return 0;
}

这是标准算法使用的确切策略,例如std::for_each()(您应该使用它而不是自己编写)1,例如:

#include <iostream>
#include <string>
#include <array>
#include <vector>
#include <algorithm>

int main() {

    std::array<int, 4> arr = { 0, 1, 2, 3 };
    std::for_each(arr.begin(), arr.end(),
        [](int value) { std::cout << "value is : " << value << std::endl; }
    );

    std::vector<std::string> v = { "hello", "world", "joe", "smoe" };
    std::for_each(v.begin(), v.end(),
        [](const std::string &value) { std::cout << "value is : " << value << std::endl; }
    );

    return 0;
}

1:C++20 引入了一个新的Ranges library,它具有作用于整个容器的算法。

【讨论】:

    【解决方案2】:

    因为std::array 的第二个模板参数是std::size_t,而不是unsigned int。编译器无法推断模板函数中类型之间的转换。碰巧你的编译器中的std::size_tlong unsigned int 上的一个typedef,所以这就是它的建议。

    您可以通过两种方式使其工作:

    1. 将模板类型改为std::size_t

    2. 调用时显式提供模板参数:

      foreach&lt;4&gt;(v, print);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-02
      • 2012-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多