我正在探索boost库代码,并发现了以下奇怪的struct定义。
struct add_ints_only
{
template<typename T>
struct result;
template <typename State, typename T>
struct result<add_ints_only(State, T)> // what's going on here?
{
typedef typename boost::remove_const<
typename boost::remove_reference<State>::type>::type type;
};
template <typename State, typename T>
State
operator()(State const& state, T const& /*x*/) const
{
return state;
}
int
operator()(int state, int x) const
{
return x + state;
}
};
它的用途是什么?
答案 0 :(得分:3)
result
部分专注于功能类型add_ints_only(State, T)
。
目的是想要知道仿函数add_ints_only
返回特定参数类型的类型的代码可以通过以下方式查询:
typedef typename add_ints_only::result<add_ints_only(arg1_type, arg2_type)>::type
result_type;
e.g。
template<typename U, typename V> void foo(U u, V v) {
typename add_ints_only::result<add_ints_only(arg1_type, arg2_type)>::type
result = add_ints_only()(u, v);
}
这对于可以根据operator()
参数类型返回不同类型的仿函数很有用。
答案 1 :(得分:3)
我猜你正在寻找一些Boost.Fusion的东西或类似的东西。
特别是add_ints_only是Polymorphic Function Object概念的模型。
多态函数对象提供多态运算符(),可能会重载或可能是模板。 operator()的结果类型可能因其参数类型而异。
它与STL中的Adaptable Unary Function概念类似,它应该提供嵌套的:: result_type。
但是多态函数对象的结果类型可能因传递给operator()的参数类型而异。因此,应该使用比single :: result_type更强大的功能来获取基于operator()参数类型的结果类型。
template <typename State, typename T>
struct result<add_ints_only(State, T)> // ...
此语法是类的部分特化。
add_ints_only(State, T)
是返回add_ints_only并将Stage和T作为参数的函数类型。
本身,这种类型并非没有意义 - 你不会返回add_ints_only。它只是方便的类型参数传递形式 - 它看起来像add_ints_only函数的调用。它允许对不同数量的参数进行专门化。
这是如何运作的:
#include <boost/utility/result_of.hpp>
#include <typeinfo>
#include <iostream>
#include <ostream>
using namespace std;
struct PolymorphicFunctionObject
{
template<typename T> struct result;
template<typename Arg>
struct result< PolymorphicFunctionObject(Arg) >
{
typedef Arg type;
};
template<typename Arg1,typename Arg2>
struct result< PolymorphicFunctionObject(Arg1,Arg2) >
{
typedef Arg2 type;
};
template<typename Arg>
Arg operator()(Arg t) const
{
return t;
}
template<typename Arg1,typename Arg2>
Arg2 operator()(Arg1 t1,Arg2 t2) const
{
return t2;
}
};
int main()
{
cout << typeid
(
PolymorphicFunctionObject::result< PolymorphicFunctionObject(int) >::type
).name() << endl;
// Output is - int
cout << typeid
(
PolymorphicFunctionObject::result< PolymorphicFunctionObject(char,double) >::type
).name() << endl;
// Output is - double
// -----------------
// Or using boost::result_of, which queries ::result internally:
cout << typeid
(
boost::result_of< PolymorphicFunctionObject(short) >::type
).name() << endl;
// Output is - short
cout << typeid
(
boost::result_of< PolymorphicFunctionObject(char,float) >::type
).name() << endl;
// Output is - float
// ------------------
// Or using C++11 decltype:
cout << typeid
(
decltype( PolymorphicFunctionObject()( long() ) )
).name() << endl;
// Output is - long
cout << typeid
(
decltype( PolymorphicFunctionObject()( long(),unsigned() ) )
).name() << endl;
// Output is - unsigned int
}
如您所见,结果类型查询语法:
boost::result_of< PolymorphicFunctionObject(short) >::type
boost::result_of< PolymorphicFunctionObject(char,float) >::type
看起来类似于普通函数调用。
P.S。在C ++ 11中,由于存在decltype,这个东西不需要,可以用来自动获取结果类型。例如:
decltype( PolymorphicFunctionObject()( long(),unsigned() ) )