C++ 使用mpl::if、boost::function和要作废的typedef时出现问题

C++ 使用mpl::if、boost::function和要作废的typedef时出现问题,c++,boost,metaprogramming,boost-function,boost-mpl,C++,Boost,Metaprogramming,Boost Function,Boost Mpl,我是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.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;
}
模板
结构A{
typedef boost::函数类型::参数类型P;
typedef typename boost::函数类型::结果类型::类型R;
typedef typename boost::mpl::if_u,
boost::函数,
boost::函数>::类型TTT;
A(){}
};
int main(int argc,const char*argv[]{
A好的;//正在工作
编译错误;//不工作
返回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’
xxx.cxx:在“A”的实例化中:
xxx.cxx:108:25:从此处实例化
xxx.cxx:100:77:错误:参数类型无效
'boost::mpl::aux::wrapped_type::type'
xxx.cxx:100:77:错误:在声明“A::TTT”中
这里的问题是什么,我该如何解决


据我所知,只有
mpl::if_
的选定部分应由编译器进行计算……

首先,为了解释错误,应该注意,在参数列表中使用typedef来
void
是一个错误。这两个GCC错误报告(和)描述了问题,指出这是标准的要求

因此,基本上,根据标准§8.3.5/2,这是合法的:

void foo(void);
虽然这不是:

typedef void type;
void foo(type);
这就解释了为什么您首先需要
if
。现在,为了解释为什么仍然存在错误,您需要了解MPL中的延迟求值仅适用于元函数:只要您不访问元函数中的
类型
,它就不会被求值。这里,
if_
的参数没有被计算(因为它们不是元函数,所以不能计算),但这并不意味着它们没有被实例化

为了克服这个问题,您可以将
函数
实例化嵌入到可以延迟计算的元函数中:

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() { }
};

如果需要,无需更多

我在名称空间“boost::function\u types”中得到了
“result\u type”没有命名类型
p
TTT
声明中没有使用,这是正常的还是打字错误(我们不知道您想要实现什么,所以很难说)?为什么是否决票还是否决票?这是一个完全合理的问题,可以回答,也可以帮助他人。这让我了解到,在参数列表中使用typedef无效是一个错误,这似乎是问题的充分理由:)。它可以帮助其他人使用MPL和/或
boost/std::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() { }
};