result_of

  • result_ofについて・・・参照
  • result_ofの利用者は大胆に型を訊ねて良い
    • 実際にどのように引数を受け取るかは関数オブジェクトの実装者の自由
  • result_of::typeは常に成功し、デフォルト値(void)を持っている・・・参照
    • 引数のない(つまりテンプレートでない)operator()は、operator()の宣言は、クラステンプレートのインスタンス化と同時にインスタンス化されるので、それに備えるため
    • 戻り値がvoidではない場合は、boost::result_ofを直接特殊化しなければならない
  • result_ofがみんなに使われるころにはたぶんautoもあるので日の目を見ない気がする

[]#include[] []<iostream>[]
[]#include[] []<string>[]
[]#include[] []<boost/mpl/assert.hpp>[]
[]#include[] []<boost/mpl/identity.hpp>[]
[]#include[] []<boost/type_traits/is_reference.hpp>[]
[]#include[] []<boost/type_traits/remove_reference.hpp>[]
[]#include[] []<boost/utility/result_of.hpp>[]

[]struct[] []foo_function[]
[]{[]
[]template[][]< [][]class[] []F[][] >[]
[]struct[] []result[][];[]

[]// 2ary[]
[]template[][]< [][]class[] []F[][], [][]class[] []A0[][], [][]class[] []A1[][] >[]
[]struct[] []result[][]<[][]F[][]([][]A0[][], [][]A1[][])> :[]
[]boost[][]::[][]remove_reference[][]<[][]A0[][]>[]
[] { };[]

[]template[][]< [][]class[] []A0[][], [][]class[] []A1[][] >[]
[]A0[] []operator[][]()([][]A0[] []a0[][], [][]A1[] []a1[][]) [][]const[]
[] {[]
[]return[] []a0[][] + [][]a1[][];[]
[] }[]

[]// 1ary[]
[]template[][]< [][]class[] []F[][], [][]class[] []A0[][] >[]
[]struct[] []result[][]<[][]F[][]([][]A0[][])>[]
[] {[]
[]BOOST_MPL_ASSERT[][](( [][]boost[][]::[][]is_reference[][]<[][]A0[][]> ));[]
[]typedef[] []std[][]::[][]string[] []type[][];[]
[] };[]

[]template[][]< [][]class[] []A0[][] >[]
[]std[][]::[][]string[] []operator[][]()([][]A0[][]& [][]a1[][]) [][]const[]
[] {[]
[] ++[][]a1[][];[]
[]return[] []"incremented"[][];[]
[] }[]

[]// 0ary[]

[]/*[]
[] これは決して呼ばれない![]
[] template< class F >[]
[] struct result<F()> :[]
[] boost::mpl::identity<int>[]
[] { };[]
[] */[]

[]int[] []operator[][]()() [][]const[]
[] {[]
[]return[] []777[][];[]
[] }[]
[]};[]


[]const[] []foo_function[][]& [][]foo[][] = [][]foo_function[][]();[]


[]namespace[] []boost[][] {[]

[]// 直接specializeする[]
[]template[][]< >[]
[]struct[] []result_of[][]<[][]foo_function[][]()> :[]
[]mpl[][]::[][]identity[][]<[][]int[][]>[]
[] { };[]

[]} [][]// namespace boost[]


[]void[] []result_of_test[][]()[]
[]{[]
[]int[] []x[][] = [][]10[][], [][]y[][] = [][]20[][];[]
[]boost[][]::[][]result_of[][]<[][]foo_function[][]([][]int[][], [][]int[][])>::[][]type[] []r1[][] = [][]foo[][]([][]x[][], [][]y[][]);[]
[]boost[][]::[][]result_of[][]<[][]foo_function[][]([][]int[][]&)>::[][]type[] []r2[][] = [][]foo[][]([][]x[][]);[]
[]boost[][]::[][]result_of[][]<[][]foo_function[][]()>::[][]type[] []r3[][] = [][]foo[][]();[]

[]std[][]::[][]cout[][] << [][]r1[][] << [][]", "[][] << [][]r2[][] << [][]":"[][] << [][]x[][] << [][]", "[][] << [][]r3[][] << [][]std[][]::[][]endl[][];[]
[]// output: 30, incremented:11, 777[]
[]}[]