C++/C++11中头文件functional的使用
<functional>是C++標準庫中的一個頭文件,定義了C++標準中多個用于表示函數對象(function object)的類模板,包括算法操作、比較操作、邏輯操作;以及用于綁定函數對象的實參值的綁定器(binder)。這些類模板的實例是具有函數調用運算符(function call operator)的C++類,這些類的實例可以如同函數一樣調用。不必寫新的函數對象,而僅是組合預定義的函數對象與函數對象適配器(function object adaptor),就可以執行非常復雜的操作。
std::bind:將一個或多個參數綁定到函數對象,更詳細的用法可參考 ?http://blog.csdn.net/fengbingchun/article/details/52613910? ;
std::is_bind_expression:用于判斷指定表達式是否為std::bind函數返回的結果類型;
std::reference_wrapper:類模板,用于包裝對一個實例的引用,它是可拷貝和可賦值的;
std::ref:構造一個適當的std::reference_wrapper類型的對象來保存對elem(實例對象)的引用;
std::cref:構造一個適當的std::reference_wrapper類型的對象來保存對elem(實例對象)的const 引用;
std::mem_fn:將成員函數轉換為函數對象;
std::not1:返回一個對謂詞(一元函數)的結果取反的函數對象;
std::not2:返回一個對二元謂詞(二元函數)的結果取反的函數對象;
std::unary_negate:一元謂詞對象類,其調用時把另一個一元謂詞的返回值取反;
std::binary_negate:二元謂詞對象類,其調用時把另一個二元謂詞的返回值取反;
std::function:類模版,是一種通用、多態的函數封裝。std::function的實例可以對任何可以調用的目標實體進行存儲、復制、和調用操作,這些目標實體包括普通函數、Lambda表達式、函數指針、以及其它函數對象等,更詳細的用法可參考 ?http://blog.csdn.net/fengbingchun/article/details/52562918 ;
std::and:二元謂詞對象類, x& y;
std::or:二元謂詞對象類, x |y;
std::xor:二元謂詞對象類, x ^y;
std::plus:二元謂詞對象類, x +y;
std::minus:二元謂詞對象類, x -y;
std::multiplies:二元謂詞對象類, x *y;
std::divides:二元謂詞對象類, x /y;
std::modulus:二元謂詞對象類, x %y;
std::negate:一元謂詞對象類, ?-x;
std::equal_to: 二元謂詞對象類, x ==y;
std::not_equal_to:二元謂詞對象類, x != y;
std::greater: 二元謂詞對象類, x >y;
std::less: 二元謂詞對象類, x <y;
std::greater_equal:二元謂詞對象類, x >= y;
std::less_equal:二元謂詞對象類, x <= y;
std::logical_and:二元謂詞對象類, x && y;
std::logical_or:二元謂詞對象類, x || y;
std::logical_not:一元謂詞對象類, !x;
std::bad_function_call:這是一個被拋出的異常類,用于表示被調用的函數對象為空;
std::hash:一元函數對象類,用于定義標準庫使用的默認散列函數;
std::placeholders:命名空間,該命名空間聲明一個未指定數量的對象:_1,_2,_3,...,用于在函數std::bind的調用中指定占位符;
std::is_placeholder:用于判斷指定表達式是否為std::placeholders中定義的placeholder類型。
C++11中也廢棄了一些舊式的函數對象。
下面是從其它文章中copy的<functional>測試代碼,詳細內容介紹可以參考對應的reference:
?
#include "functional.hpp"
#include <functional>
#include <iostream>
#include <algorithm>
#include <utility>
#include <iterator>
#include <numeric>
#include <string>// reference: http://www.cplusplus.com/reference/functional/namespace functional_ {
///
// a function: (also works with function object: std::divides<double> my_divide;)
static double my_divide(double x, double y) { return x / y; }struct MyPair {double a, b;double multiply() { return a*b; }
};int test_functional_bind()
{using namespace std::placeholders; // adds visibility of _1, _2, _3,...// binding functions:auto fn_five = std::bind(my_divide, 10, 2); // returns 10/2std::cout << fn_five() << '\n'; // 5auto fn_half = std::bind(my_divide, _1, 2); // returns x/2std::cout << fn_half(10) << '\n'; // 5auto fn_invert = std::bind(my_divide, _2, _1); // returns y/xstd::cout << fn_invert(10, 2) << '\n'; // 0.2auto fn_rounding = std::bind<int>(my_divide, _1, _2); // returns int(x/y)std::cout << fn_rounding(10, 3) << '\n'; // 3MyPair ten_two{ 10, 2 };// binding members:auto bound_member_fn = std::bind(&MyPair::multiply, _1); // returns x.multiply()std::cout << bound_member_fn(ten_two) << '\n'; // 20auto bound_member_data = std::bind(&MyPair::a, ten_two); // returns ten_two.astd::cout << bound_member_data() << '\n'; // 10return 0;
}//
int test_functional_cref()
{int foo(10);auto bar = std::cref(foo);std::cout << bar << '\n'; // 10++foo;std::cout << bar << '\n'; // 11return 0;
}/
int test_functional_ref()
{int foo(10);auto bar = std::ref(foo);std::cout << bar << '\n'; // 10++bar;std::cout << foo << '\n'; // 11std::cout << bar << '\n'; // 11return 0;
}//
struct int_holder {int value;int triple() { return value * 3; }
};int test_functional_mem_fn()
{int_holder five{ 5 };// call member directly:std::cout << five.triple() << '\n'; // 15// same as above using a mem_fn:auto triple = std::mem_fn(&int_holder::triple);std::cout << triple(five) << '\n'; // 15return 0;
}//
struct IsOdd {bool operator() (const int& x) const { return x % 2 == 1; }typedef int argument_type;
};int test_functional_not1()
{int values[] = { 1, 2, 3, 4, 5 };int cx = std::count_if(values, values + 5, std::not1(IsOdd()));std::cout << "There are " << cx << " elements with even values.\n"; // 2return 0;
}int test_functional_not2()
{int foo[] = { 10, 20, 30, 40, 50 };int bar[] = { 0, 15, 30, 45, 60 };std::pair<int*, int*> firstmatch, firstmismatch;firstmismatch = std::mismatch(foo, foo + 5, bar, std::equal_to<int>());firstmatch = std::mismatch(foo, foo + 5, bar, std::not2(std::equal_to<int>()));std::cout << "First mismatch in bar is " << *firstmismatch.second << '\n'; // 0std::cout << "First match in bar is " << *firstmatch.second << '\n'; // 30return 0;
}//
int test_functional_binary_negate()
{std::equal_to<int> equality;std::binary_negate < std::equal_to<int> > nonequality(equality);int foo[] = { 10, 20, 30, 40, 50 };int bar[] = { 0, 15, 30, 45, 60 };std::pair<int*, int*> firstmatch, firstmismatch;firstmismatch = std::mismatch(foo, foo + 5, bar, equality);firstmatch = std::mismatch(foo, foo + 5, bar, nonequality);std::cout << "First mismatch in bar is " << *firstmismatch.second << "\n"; // 0std::cout << "First match in bar is " << *firstmatch.second << "\n"; // 30return 0;
}struct IsOdd_class {bool operator() (const int& x) const { return x % 2 == 1; }typedef int argument_type;
} IsOdd_object;int test_functional_unary_negate()
{std::unary_negate<IsOdd_class> IsEven_object(IsOdd_object);int values[] = { 1, 2, 3, 4, 5 };int cx;cx = std::count_if(values, values + 5, IsEven_object);std::cout << "There are " << cx << " elements with even values.\n"; // 2return 0;
}// a function:
static int half(int x) { return x / 2; }// a function object class:
struct third_t {int operator()(int x) { return x / 3; }
};// a class with data members:
struct MyValue {int value;int fifth() { return value / 5; }
};int test_functional_function()
{std::function<int(int)> fn1 = half; // functionstd::function<int(int)> fn2 = ? // function pointerstd::function<int(int)> fn3 = third_t(); // function objectstd::function<int(int)> fn4 = [](int x){return x / 4; }; // lambda expressionstd::function<int(int)> fn5 = std::negate<int>(); // standard function objectstd::cout << "fn1(60): " << fn1(60) << '\n'; // 30std::cout << "fn2(60): " << fn2(60) << '\n'; // 30std::cout << "fn3(60): " << fn3(60) << '\n'; // 20std::cout << "fn4(60): " << fn4(60) << '\n'; // 15std::cout << "fn5(60): " << fn5(60) << '\n'; // -06// stuff with members:std::function<int(MyValue)> value = &MyValue::value; // pointer to data memberstd::function<int(MyValue)> fifth = &MyValue::fifth; // pointer to member functionMyValue sixty{ 60 };std::cout << "value(sixty): " << value(sixty) << '\n'; // 60std::cout << "fifth(sixty): " << fifth(sixty) << '\n'; // 12return 0;
}int test_functional_reference_wrapper()
{int a(10), b(20), c(30);// an array of "references":std::reference_wrapper<int> refs[] = { a, b, c };std::cout << "refs:";for (int& x : refs) std::cout << ' ' << x; // 10 20 30std::cout << '\n';return 0;
}//
int test_functional_bit()
{
{int values[] = { 100, 200, 300, 400, 500 };int masks[] = { 0xf, 0xf, 0xf, 255, 255 };int results[5];std::transform(values, std::end(values), masks, results, std::bit_and<int>());std::cout << "results:";for (const int& x : results)std::cout << ' ' << x; // 4 8 12 144 244std::cout << '\n';
}{int flags[] = { 1, 2, 4, 8, 16, 32, 64, 128 };int acc = std::accumulate(flags, std::end(flags), 0, std::bit_or<int>());std::cout << "accumulated: " << acc << '\n'; // 255
}{int flags[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int acc = std::accumulate(flags, std::end(flags), 0, std::bit_xor<int>());std::cout << "xor: " << acc << '\n'; // 11
}return 0;
}//
int test_functional_arithmetic()
{
{int first[] = { 1, 2, 3, 4, 5 };int second[] = { 10, 20, 30, 40, 50 };int results[5];std::transform(first, first + 5, second, results, std::plus<int>());for (int i = 0; i<5; i++)std::cout << results[i] << ' '; // 11 22 33 44 55std::cout << '\n';
}{int numbers[] = { 10, 20, 30 };int result;result = std::accumulate(numbers, numbers + 3, 100, std::minus<int>());std::cout << "The result of 100-10-20-30 is " << result << ".\n"; // 40
}{int numbers[9];int factorials[9];for (int i = 0; i<9; i++) numbers[i] = i + 1;std::partial_sum(numbers, numbers + 9, factorials, std::multiplies<int>());for (int i = 0; i<9; i++)std::cout << numbers[i] << "! is " << factorials[i] << '\n'; // 1 2 6 24 120 720 5040 40320 362880
}{int first[] = { 10, 40, 90, 40, 10 };int second[] = { 1, 2, 3, 4, 5 };int results[5];std::transform(first, first + 5, second, results, std::divides<int>());for (int i = 0; i<5; i++)std::cout << results[i] << ' '; // 10 20 30 10 2std::cout << '\n';
}{int numbers[] = { 1, 2, 3, 4, 5 };int remainders[5];std::transform(numbers, numbers + 5, remainders, std::bind2nd(std::modulus<int>(), 2));for (int i = 0; i < 5; i++)std::cout << numbers[i] << " is " << (remainders[i] == 0 ? "even" : "odd") << '\n';
}{int numbers[] = { 10, -20, 30, -40, 50 };std::transform(numbers, numbers + 5, numbers, std::negate<int>());for (int i = 0; i<5; i++)std::cout << numbers[i] << ' '; // -10 20 -30 40 -50std::cout << '\n';
}return 0;
}///
int test_functional_compare()
{
{std::pair<int*, int*> ptiter;int foo[] = { 10, 20, 30, 40, 50 };int bar[] = { 10, 20, 40, 80, 160 };ptiter = std::mismatch(foo, foo + 5, bar, std::equal_to<int>());std::cout << "First mismatching pair is: " << *ptiter.first; // 30std::cout << " and " << *ptiter.second << '\n'; // 40
}{int numbers[] = { 10, 10, 10, 20, 20 };int* pt = std::adjacent_find(numbers, numbers + 5, std::not_equal_to<int>()) + 1;std::cout << "The first different element is " << *pt << '\n'; // 20
}{int numbers[] = { 20, 40, 50, 10, 30 };std::sort(numbers, numbers + 5, std::greater<int>());for (int i = 0; i<5; i++)std::cout << numbers[i] << ' '; // 50 40 30 20 10std::cout << '\n';
}{int foo[] = { 10, 20, 5, 15, 25 };int bar[] = { 15, 10, 20 };std::sort(foo, foo + 5, std::less<int>()); // 5 10 15 20 25std::sort(bar, bar + 3, std::less<int>()); // 10 15 20if (std::includes(foo, foo + 5, bar, bar + 3, std::less<int>()))std::cout << "foo includes bar.\n"; // foo includes bar
}{int numbers[] = { 20, -30, 10, -40, 0 };int cx = std::count_if(numbers, numbers + 5, std::bind2nd(std::greater_equal<int>(), 0));std::cout << "There are " << cx << " non-negative elements.\n"; // 3
}{int numbers[] = { 25, 50, 75, 100, 125 };int cx = std::count_if(numbers, numbers + 5, std::bind2nd(std::less_equal<int>(), 100));std::cout << "There are " << cx << " elements lower than or equal to 100.\n"; // 4
}return 0;
}///
int test_functional_logical()
{
{bool foo[] = { true, false, true, false };bool bar[] = { true, true, false, false };bool result[4];std::transform(foo, foo + 4, bar, result, std::logical_and<bool>());std::cout << std::boolalpha << "Logical AND:\n";for (int i = 0; i<4; i++)std::cout << foo[i] << " AND " << bar[i] << " = " << result[i] << "\n"; // true false false false
}{bool foo[] = { true, false, true, false };bool bar[] = { true, true, false, false };bool result[4];std::transform(foo, foo + 4, bar, result, std::logical_or<bool>());std::cout << std::boolalpha << "Logical OR:\n";for (int i = 0; i<4; i++)std::cout << foo[i] << " OR " << bar[i] << " = " << result[i] << "\n"; // true true true false
}{bool values[] = { true, false };bool result[2];std::transform(values, values + 2, result, std::logical_not<bool>());std::cout << std::boolalpha << "Logical NOT:\n";for (int i = 0; i<2; i++)std::cout << "NOT " << values[i] << " = " << result[i] << "\n"; // false true
}return 0;
}int test_functional_bad_function_call()
{std::function<int(int, int)> foo = std::plus<int>();std::function<int(int, int)> bar;try {std::cout << foo(10, 20) << '\n'; // 30std::cout << bar(10, 20) << '\n';} catch (std::bad_function_call& e){std::cout << "ERROR: Bad function call\n"; // ERROR: Bad function call}return 0;
}//
int test_functional_hash()
{char nts1[] = "Test";char nts2[] = "Test";std::string str1(nts1);std::string str2(nts2);std::hash<char*> ptr_hash;std::hash<std::string> str_hash;std::cout << "same hashes:\n" << std::boolalpha;std::cout << "nts1 and nts2: " << (ptr_hash(nts1) == ptr_hash(nts2)) << '\n'; // falsestd::cout << "str1 and str2: " << (str_hash(str1) == str_hash(str2)) << '\n'; // truereturn 0;
}/
int test_functional_is_bind_expression()
{using namespace std::placeholders; // introduces _1auto increase_int = std::bind(std::plus<int>(), _1, 1);std::cout << std::boolalpha;std::cout << std::is_bind_expression<decltype(increase_int)>::value << '\n'; // truereturn 0;
}/
int test_functional_is_placeholder()
{using namespace std::placeholders; // introduces _1std::cout << std::is_placeholder<decltype(_1)>::value << '\n'; // 1std::cout << std::is_placeholder<decltype(_2)>::value << '\n'; // 2std::cout << std::is_placeholder<int>::value << '\n'; // 0return 0;
}} // namespace functional_
GitHub: https://github.com/fengbingchun/Messy_Test
?
總結
以上是生活随笔為你收集整理的C++/C++11中头文件functional的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++/C++11中头文件iterato
- 下一篇: 深度学习中的最大似然估计简介