使用mpl::if_、boost::函数和void类型定义的问题
Problems using mpl::if_, boost::function, and a typedef to void
我是Boost的新手。MPL库,并有一些"初学者问题"
看这个例子:
template < typename F >
struct A {
typedef boost::function_types::parameter_types<F> P;
typedef typename boost::function_types::result_type<F>::type R;
typedef typename boost::mpl::if_< boost::is_same< R, void >,
boost::function< void ( void ) > ,
boost::function< void ( R ) > >::type TTT;
A() { }
};
int main(int argc, const char *argv[]) {
A<int(int, float)> ok; // working
A<void(int, float)> compile_error; // non-working
return 0;
}
编译时得到:
xxx.cxx: In instantiation of ‘A<void(int, float)>’:
xxx.cxx:108:25: instantiated from here
xxx.cxx:100:77: error: invalid parameter type
‘boost::mpl::aux::wrapped_type<boost::mpl::aux::type_wrapper<void>
>::type’
xxx.cxx:100:77: error: in declaration ‘A<F>::TTT’
这里的问题是什么,我该如何解决它?
在我的理解中,编译器只对mpl::if_
中选定的部分求值....
首先,要解释这个错误,应该注意在参数列表中对void
使用类型定义是一个错误。这两个GCC bug报告(32058和9278)描述了这个问题,并指出这是标准的要求。
所以基本上,根据标准§8.3.5/2,这是合法的:
void foo(void);
而这不是:
typedef void type;
void foo(type);
这解释了为什么你首先需要if_
。现在,为了解释为什么仍然会出现错误,您需要理解MPL中的惰性求值仅适用于元函数:只要不访问元函数中的type
,它就不会被求值。这里,if_
的参数没有计算(它们不能,因为它们不是元函数),但这并不意味着它们没有被实例化。
为了克服这个问题,您可以将function
实例化嵌入到可以惰性求值的元函数中:
template < typename R, typename P >
struct get_function
{
typedef boost::function< R (P) > type;
};
template < typename F >
struct A {
typedef boost::function_types::parameter_types<F> P;
typedef typename boost::function_types::result_type<F>::type R;
typedef typename
boost::mpl::if_<
boost::is_same< R, void >,
boost::mpl::identity< boost::function< void (void) > > ,
get_function< void, R >
>::type::type TTT;
A() { }
};
这样,错误的void (typedef_to_void)
就不会出现。
一个更好的解决方案甚至是为void
的情况专门化get_function
元函数:
template < typename R, typename P >
struct get_function
{
typedef boost::function< R (P) > type;
};
template < typename R >
struct get_function< R, void >
{
typedef boost::function< R (void) > type;
};
template < typename F >
struct A {
typedef boost::function_types::parameter_types<F> P;
typedef typename boost::function_types::result_type<F>::type R;
typedef typename get_function< void, R >::type TTT;
A() { }
};
不需要更多的if_
!
相关文章:
- 引用一个已擦除类型(void*)的指针
- 错误:"cast"未命名类型void setCastDescription(std::string
- 错误:对类型 'const ItemInstance' 的引用无法绑定到类型 'void' 的右值
- 从类型"void*"到函数指针的强制转换无效
- C++错误(从不兼容的类型"void"分配给树节点*)
- 从不兼容的类型 'void (Button::*)(int)' 分配给'void (*)(int)'
- 从类型"void*"到类member_function指针的强制转换无效
- 将 false 转换为指针类型 void*
- 称为对象类型"void (B::*)(int)"不是函数或函数指针
- CPP(15): 错误 C2182:"输入":"非法使用类型"void"
- 类型 "void (Biometria::*)(char *idSensor, GRCAP_FINGER_EVENTS event)" 的参数与类型 "GRCAP_STATUS_EVENT_PROC
- Xcode 变量具有不完整的类型 void
- qvector.h(74):错误 C2182:'t':非法使用类型 'void'
- C 函数声明对类型"void(*fcn)(void*)"参数的说明
- C++从类型“void*”转换为类型“double”无效
- LAMBDA 错误:类型 'void' 的条件表达式是非法的
- 类型 void 的值不允许在 C++ 中出错
- 从类型 'MyStruct' 转换为类型 'void*' 无效
- C++,参数类型(void*&)的目的是什么?
- 无法将不完整类型'void *'的参数转换为'const bitData'