The function template std::memfn creates wrapper objects that are capable of storing, copying, and calling pointers to other members. To invoke a std::memfn, we can use either references or pointers (including smarcpp tutorialers) to an object.
The C++ Standard Library, namely the header, contains the function adapter std::memfunref. It is included in the larger family of function adapters, which also includes std::memfun and std::memfn, it is intended to modify member functions for usage in function objects and algorithms. Use the std::memfunref to create function objects that can call a specified member function on instances of a given class . Std::memfunref requires a reference to the object rather than a pointer , in contrast to std::mem_fun, which accepts the latter. It becomes especially helpful in situations where you have an object container and we wish to apply a member function to every object in the container consistently.
Syntax:
It has the following syntax:
template< class Res, class T, class Arg >
std::const_mem_fun1_ref_t<Res,T,Arg> mem_fun_ref( Res (T::*f)(Arg) const );
Example 1:
Let us take an example to illustrate the std::memfunref function in C++.
#include <functional>
#include <iostream>
#include <memory>
struct Foo
{
void say_hello()
{
std::cout << "Greetings from Foo!\n";
}
void print_value(int value)
{
std::cout << "Value: " << value << '\n';
}
int add_numbers(int x, int y)
{
return x + y;
}
template<typename... Args> int sum_all(Args... args)
{
return (args + ...);
}
auto calculate_sum(auto... args) // C++20 required
{
return (args + ...);
}
int data = 100;
};
int main()
{
auto obj = Foo{};
auto greet = std::mem_fn(&Foo::say_hello);
greet(obj);
auto print = std::mem_fn(&Foo::print_value);
print(obj, 42);
auto access_data = std::mem_fn(&Foo::data);
std::cout << "Data: " << access_data(obj) << '\n';
auto add = std::mem_fn(&Foo::add_numbers);
std::cout << "Sum: " << add(obj, 5, 7) << '\n';
auto ptr = std::make_unique<Foo>();
std::cout << "Accessed Data: " << access_data(ptr) << '\n';
std::cout << "Sum with Pointer: " << add(ptr, 10, 20) << '\n';
auto sum_fn = std::mem_fn(&Foo::sum_all<short, int, long>);
std::cout << "Sum of All: " << sum_fn(ptr, 1, 2, 3) << '\n';
auto calc_sum = std::mem_fn(&Foo::calculate_sum<short, int, float, double>);
std::cout << "Calculated Sum: " << calc_sum(ptr, 5, 7, 10.0f, 13.0) << '\n';
}
Output:
Greetings from Foo!
Value: 42
Data: 100
Sum: 12
Accessed Data: 100
Sum with Pointer: 30
Sum of All: 6
Calculated Sum: 35
Example 2:
Let us take another example to illustrate the std::memfunref function in C++.
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
class MyClass {
public:
MyClass(int val) : value(val) {}
// Member function to be adapted
void printValue() const {
std::cout << "Value: " << value << std::endl;
}
int getValue() const {
return value;
}
private:
int value;
};
int main() {
// Create instances of MyClass
std::vector<MyClass> vec;
vec.emplace_back(10);
vec.emplace_back(20);
vec.emplace_back(30);
// Use std::mem_fun_ref to adapt the member function printValue
std::for_each(vec.begin(), vec.end(), std::mem_fun_ref(&MyClass::printValue));
// Using std::mem_fun_ref to adapt member function returning int
auto getValue = std::mem_fun_ref(&MyClass::getValue);
std::vector<int> values;
std::transform(vec.begin(), vec.end(), std::back_inserter(values), getValue);
// Print the extracted values
std::cout << "Extracted Values:" << std::endl;
for (const auto& val : values) {
std::cout << val << " ";
}
std::cout << std::endl;
return 0;
}
Output:
Value: 10
Value: 20
Value: 30
Extracted Values:
10 20 30
Example 3:
Let us take another example to illustrate the std::memfunref function in C++.
#include <iostream>
#include <vector>
#include <functional> // for std::mem_fun_ref
class Person {
private:
std::string name;
int age;
public:
Person(const std::string& n, int a) : name(n), age(a) {}
void greet() const {
std::cout << "Hello, I'm " << name << " and I'm " << age << " years old." << std::endl;
}
};
int main() {
std::vector<Person> people;
people.push_back(Person("Alice", 30));
people.push_back(Person("Bob", 25));
people.push_back(Person("Charlie", 40));
// Create a mem_fun_ref function object for Person::greet
auto greetFunc = std::mem_fun_ref(&Person::greet);
// Call the greet function on each person in the vector
for (const auto& person : people) {
greetFunc(person);
}
return 0;
}
Output:
Hello, I'm Alice and I'm 30 years old.
Hello, I'm Bob and I'm 25 years old.
Hello, I'm Charlie and I'm 40 years old.
Conclusion:
In conclusion, use the flexible function adapter std::memfunref in C++, which is provided by the Standard Library, to create function objects that can call specific member functions on instances of a given class. In particular, std::memfunref is useful when working with containers of objects because it accepts a reference to the object instead of a pointer, as does std::memfun. Std::memfun_ref makes member function calls more manageable and readable by encapsulating them into function objects, which makes it easier to use member functions in generic algorithms or function objects. Working with object-oriented code in C++ is made easier and more flexible by this useful tool, which also makes the most of the Standard Library. It allows for cleaner and more expressive code.