이 글에서는 C++에서 발생하는 "invalid use of member function" 에러의 원인 및 해결 방법에 대해 자세히 설명하고 있습니다. 실무에서 사용될 수 있는 코드 예제를 기반으로, 에러의 발생 원인을 분석하고 몇 가지 해결 방법을 제시합니다.
문제상황
아래와 같은 에러가 발생한 코드를 살펴보겠습니다.
#include <iostream>
#include <vector>
#include <algorithm>
class Employee {
public:
Employee(const std::string& name, int age, double salary)
: m_name(name), m_age(age), m_salary(salary) {}
bool is_higher_salary(const Employee& other) const {
return m_salary > other.m_salary;
}
private:
std::string m_name;
int m_age;
double m_salary;
};
int main() {
std::vector<Employee> employees = {
Employee("John", 30, 50000),
Employee("Jane", 28, 55000),
Employee("Bob", 35, 60000)
};
std::sort(employees.begin(), employees.end(), Employee::is_higher_salary);
}
위 코드는 Employee 클래스의 객체들을 std::vector에 저장한 후, salary가 높은 순서로 정렬하려고 합니다. 하지만, 컴파일 시 "invalid use of member function" 에러가 발생합니다.
에러로그 내용:
error: invalid use of non-static member function 'bool Employee::is_higher_salary(const Employee&) const'
원인분석
이 에러는 std::sort 함수의 세 번째 인자로 Employee::is_higher_salary 멤버 함수를 전달하려고 했기 때문에 발생한 것입니다. 이 함수는 일반 멤버 함수이기 때문에, 객체에 속한 함수로서 호출되어야 하지만, 여기에서는 객체 없이 전달되었습니다.
C++에서 멤버 함수를 이렇게 사용하려면, 일반적으로 다음과 같은 방법이 필요합니다:
- 함수 객체 (Functor)를 사용하여 해당 멤버 함수를 호출하는 객체를 만듭니다.
- 람다 함수를 사용하여 해당 멤버 함수를 호출하는 람다를 만듭니다.
- 멤버 함수 포인터를 사용하여 해당 멤버 함수를 호출합니다.
- 멤버 함수를 정적(static) 멤버 함수로 변경하고, 이를 호출합니다.
해결방법-1 (함수 객체)
첫 번째 해결 방법은 함수 객체를 사용하는 것입니다. 이를 위해 Employee 클래스에 Comparator라는 중첩 클래스를 만들어 보겠습니다.
에러가 수정된 코드:
// ... (Employee 클래스 코드 생략)
class Employee {
// ... (생략)
public:
class Comparator {
public:
bool operator()(const Employee& e1, const Employee& e2) const {
return e1.is_higher_salary(e2);
}
};
};
int main() {
std::vector<Employee> employees = {
Employee("John", 30, 50000),
Employee("Jane", 28, 55000),
Employee("Bob", 35, 60000)
};
std::sort(employees.begin(), employees.end(), Employee::Comparator());
}
위 코드에서는 Employee::Comparator
라는 함수 객체를 만들어서, std::sort
함수의 세 번째 인자로 전달합니다. 이렇게 함으로써, Employee::is_higher_salary
함수를 호출하는데 필요한 객체를 만들어 줍니다.
해결방법-2 (람다 함수)
두 번째 해결 방법은 람다 함수를 사용하는 것입니다. 람다 함수를 사용하여, Employee::is_higher_salary
함수를 호출하는 람다를 만들어 보겠습니다.
에러가 수정된 코드:
// ... (Employee 클래스 코드 생략)
int main() {
std::vector<Employee> employees = {
Employee("John", 30, 50000),
Employee("Jane", 28, 55000),
Employee("Bob", 35, 60000)
};
std::sort(employees.begin(), employees.end(), [](const Employee& e1, const Employee& e2) {
return e1.is_higher_salary(e2);
});
}
위 코드에서는 std::sort 함수의 세 번째 인자로 람다 함수를 전달합니다. 람다 함수는 두 개의 Employee 객체를 인자로 받고, Employee::is_higher_salary 함수를 호출하여 결과를 반환합니다.