Online Book Reader

Home Category

Professional C__ - Marc Gregoire [231]

By Root 1133 0
if it takes 1 argument, the result can be used as a callback for a binary function. C++11 mem_fn() works for n-ary functions and for both containers of pointers to objects and containers of objects themselves

mem_fn(), mem_fun_ref(), and mem_fun()are not the most intuitive ways to implement the findEmptyString() function. Using C++11 lambda expressions, it can be implemented in a much more readable and elegant way. Here is the implementation using a lambda expression working on a container of objects:

void findEmptyString(const vector& strings)

{

auto end = strings.end();

auto it = find_if(strings.begin(), end,

[](const string& str){ return str.empty(); });

// Remaining of function omitted because it is the same as earlier

}

Code snippet from FunctionObjects\EmptyString.cpp

Similarly, the following uses a lambda expression working on a container of pointers to objects:

void findEmptyString(const vector& strings)

{

auto end = strings.end();

auto it = find_if(strings.begin(), end,

[](const string* str){ return str->empty(); });

// Remaining of function omitted because it is the same as earlier

}

Code snippet from FunctionObjects\EmptyStringPtr.cpp

Both mem_fun_ref() and mem_fun() have been deprecated by C++11. Use lambda expressions instead, or mem_fn().

Adapting Real Functions

You can’t use normal function pointers directly with the function adapters bind1st(), bind2nd(), not1(), or not2(), because these adapters require specific typedefs in the function objects they adapt. For example, not1() can only operate on function objects that include an argument_type typedef, while not2() requires a first_argument_type and second_argument_type typedef. The bind1st() and bind2nd() adapters require similar typedefs.

One last function adapter provided by the C++ standard library, ptr_fun(), allows you to wrap regular function pointers in a way that they can be used with the adapters. The ptr_fun() adapter is only explained here because you might encounter it in older codebases. If you are writing new code and are using a C++11 compiler, you should use lambda expressions.

As an example, suppose that you want to write a function isNumber() that returns true if every character in a string is a digit. The C++ string class provides an iterator. Thus, you can use the find_if() algorithm to search for the first nondigit in the string. If you find one, the string is not a number. The header file provides a legacy C function called isdigit(), which returns true if a character is a digit, false otherwise.

The definition of isdigit() in is not the same as isdigit() in the more traditional C library . In , the isdigit() function is defined as a macro, which makes it completely unsuitable for use in this context. In it is defined as a function.

The problem is that you want to find the first character that is not a digit, which requires the not1() adapter. However, because isdigit() is a C function, not a function object, you need to use the ptr_fun() adapter to generate a function object that can be used with not1(). The code looks as follows:

bool isNumber(const string& str)

{

auto end = str.end();

auto it = find_if(str.begin(), end, not1(ptr_fun(::isdigit)));

return (it == end);

}

Code snippet from FunctionObjects\IsNumber.cpp

Note the use of the :: scope resolution operator to specify that isdigit() should be found in the global scope.

C++11 has deprecated ptr_fun() and you should use a lambda expression instead:

bool isNumber(const string& str)

{

auto end = str.end();

auto it = find_if(str.begin(), end, [](char c){return !::isdigit(c);});

return (it == end);

}

Code snippet from FunctionObjects\IsNumber.cpp

For this example, you can also use the new C++11 find_if_not() algorithm as follows:

bool isNumber(const string& str)

{

auto end = str.end();

auto it = find_if_not(str.begin(), end, ::isdigit);

return (it == end);

}

Code snippet from FunctionObjects\IsNumber.cpp

ptr_fun() has been deprecated by C++11. Use lambda

Return Main Page Previous Page Next Page

®Online Book Reader