3

表达式 SFINAE是一种非常方便的方法,可以编写几个替代函数来做同样的事情,并选择最好的编译函数。您在函数原型中提到了关键表达式,如果它们无效,则原型将被忽略,并且有望选择另一个。

这非常方便,除了在表达式未定义的情况下声明原型。通常必须将原型集划分为相互排斥的域,因为从重载解决方案的角度来看它们可能相等,并且允许两个进入重载集会导致歧义。

人们总是可以为给定的表达式定义一个老式的特征类型,用于std::enable_if

template< typename s, typename t, typename u, typename = void >
struct is_product_serializable : std::false_type {};

template< typename s, typename t, typename u >
struct is_product_serializable< s, t, u, typename std::conditional< true, void,
   decltype( std::declval< s >() << std::declval< t >() * std::declval< u >() )
>::type >
    : std::true_type {};

如果不是需要派生一些东西false_type,那么std::conditional可以直接进入函数原型,所有这些样板都会消失。

有什么替代方案吗?也许某种方法可以降低不干扰类型推导的函数重载的等级?

4

1 回答 1

0

一种替代方法是添加一个调度程序函数,该函数添加一个虚拟参数(如标签),以便调整空间以使参数列表不同。

// "Primary" template is just a dispatcher
template< typename ... args >
void chuck( args && ... rem ) {
    return chuck_impl( 0, std::forward< args >( a ) ... );
}

// preferred alternative matches int to 0 but is controlled by SFINAE
template< typename t, typename u, typename ... args >
auto chuck_impl( int, t && a, u && b, args && ... rem )
-> typename std::conditional< true, void, decltype( blah( a, rem ... ) * b ) >::type {
    blah( a, rem ... ) * b;
}

// fallback requires int => float conversion
template< typename t, typename u, typename ... args >
void chuck_impl( float, t && a, u && b, args && ... rem ) {
    bleh( a + chuck_impl( b, rem ... ) );
}
于 2013-02-20T06:10:32.810 回答