이 글에서는 C++에서 흔히 발생하는 "no matching function for call to 'function_name'" 에러를 해결하는 방법에 대해 설명합니다. 문제 상황과 원인 분석, 그리고 두 가지 해결 방법을 자세히 살펴봅니다.
문제상황
아래는 실무에서 사용될 수 있는 코드의 예시입니다. 이 코드에서는 사용자 정의 클래스 CustomVector와 이 클래스의 인스턴스를 정렬하는 함수 sort_custom_vectors를 사용하고 있습니다.
#include <iostream>
#include <vector>
#include <algorithm>
class CustomVector {
public:
int x, y;
CustomVector(int x, int y) : x(x), y(y) {}
};
bool compare_custom_vectors(const CustomVector &a, const CustomVector &b) {
return a.x < b.x;
}
void sort_custom_vectors(std::vector<CustomVector> &vectors) {
std::sort(vectors.begin(), vectors.end(), compare_custom_vectors);
}
int main() {
std::vector<CustomVector> my_vectors;
my_vectors.push_back(CustomVector(3, 4));
my_vectors.push_back(CustomVector(1, 2));
my_vectors.push_back(CustomVector(5, 6));
sort_custom_vectors(my_vectors);
for (const auto &vec : my_vectors) {
std::cout << "CustomVector(" << vec.x << ", " << vec.y << ")\n";
}
return 0;
}
이 코드를 컴파일하면 다음과 같은 에러가 발생합니다.
에러로그 내용:
error: no matching function for call to 'sort(std::vector<CustomVector>::iterator, std::vector<CustomVector>::iterator, bool (&)(const CustomVector&, const CustomVector&))'
원인분석
이 에러는 std::sort 함수를 호출할 때 발생합니다. 이 함수는 주어진 범위의 원소들을 정렬하는데 사용되며, 세 번째 인자로 비교 함수를 전달할 수 있습니다. 비교 함수는 두 개의 인자를 받아 첫 번째 인자가 두 번째 인자보다 작은지를 판단하는 함수입니다.
여기서 발생하는 문제는 std::sort 함수가 제대로 동작하지 않는데, 이는 compare_custom_vectors 함수의 시그니처가 std::sort 함수의 요구사항과 일치하지 않기 때문입니다. std::sort 함수는 비교 함수로 **이항 술어(Binary Predicate)**를 요구합니다. 이항 술어는 두 개의 인자를 받아 bool 값을 반환하는 함수입니다.
따라서 문제 해결을 위해서는 compare_custom_vectors 함수의 시그니처를 수정해야 합니다. 이를 위한 두 가지 해결 방법을 살펴보겠습니다.
해결방법-함수 시그니처 변경
에러가 수정된 코드와 수정된 부분에 대한 주석을 포함한 예시입니다.
#include <iostream>
#include <vector>
#include <algorithm>
class CustomVector {
public:
int x, y;
CustomVector(int x, int y) : x(x), y(y) {}
};
// 변경된 부분: const를 추가하여 함수 시그니처를 수정했습니다.
bool compare_custom_vectors(const CustomVector &a, const CustomVector &b) {
return a.x < b.x;
}
void sort_custom_vectors(std::vector<CustomVector> &vectors) {
std::sort(vectors.begin(), vectors.end(), compare_custom_vectors);
}
int main() {
std::vector<CustomVector> my_vectors;
my_vectors.push_back(CustomVector(3, 4));
my_vectors.push_back(CustomVector(1, 2));
my_vectors.push_back(CustomVector(5, 6));
sort_custom_vectors(my_vectors);
for (const auto &vec : my_vectors) {
std::cout << "CustomVector(" << vec.x << ", " << vec.y << ")\n";
}
return 0;
}
수정된 코드의 작동 원리를 각각 단계별로 설명하겠습니다.
- compare_custom_vectors 함수의 시그니처를 수정하여 이항 술어 요구 사항을 충족시킵니다.
- std::sort 함수에 전달된 비교 함수가 올바른 시그니처를 갖기 때문에, 이제 std::sort 함수가 정상적으로 동작합니다.
- 코드가 컴파일되고 실행되며, CustomVector의 인스턴스가 올바르게 정렬됩니다.
해결방법-람다 함수 사용
다른 해결 방법으로 람다 함수를 사용하여 비교 함수를 std::sort 함수에 직접 전달할 수 있습니다. 이렇게 하면 함수 시그니처 문제가 자연스럽게 해결됩니다.
에러가 수정된 코드와 수정된 부분에 대한 주석을 포함한 예시입니다.
#include <iostream>
#include <vector>
#include <algorithm>
class CustomVector {
public:
int x, y;
CustomVector(int x, int y) : x(x), y(y) {}
};
void sort_custom_vectors(std::vector<CustomVector> &vectors) {
// 변경된 부분: 람다 함수를 사용하여 비교 함수를 직접 정의합니다.
std::sort(vectors.begin(), vectors.end(), [](const CustomVector &a, const CustomVector &b) {
return a.x < b.x;
});
}
int main() {
std::vector<CustomVector> my_vectors;
my_vectors.push_back(CustomVector(3, 4));
my_vectors.push_back(CustomVector(1, 2));
my_vectors.push_back(CustomVector(5, 6));
sort_custom_vectors(my_vectors);
for (const auto &vec : my_vectors) {
std::cout << "CustomVector(" << vec.x << ", " << vec.y << ")\n";
}
return 0;
}
수정된 코드의 작동 원리를 각각 단계별로 설명하겠습니다.
- sort_custom_vectors 함수 내에서 람다 함수를 사용하여 비교 함수를 정의하고, 이를 std::sort 함수의 세 번째 인자로 전달합니다. 람다 함수는 이항 술어 요구 사항을 충족시키는 시그니처를 갖습니다.
- 람다 함수를 사용하면 별도의 비교 함수를 정의할 필요가 없기 때문에, 코드가 간결해집니다.
- std::sort 함수에 전달된 람다 함수가 올바른 시그니처를 갖기 때문에, 이제 std::sort 함수가 정상적으로 동작합니다.
- 코드가 컴파일되고 실행되며, CustomVector의 인스턴스가 올바르게 정렬됩니다.
참고링크
- 관련 에러에 대한 공식 문서의 하이퍼링크: std::sort - C++ Reference