使用__if_exists的好处有哪些案例?

7

何时使用__if_exists而不编写大量低质量代码?

看起来这个关键字就像C预处理器指令,但是它在预处理器之后被处理。而且IntelliSense不解析它并将代码标记为死亡或活动状态。这些组合使得分析使用__if_exists编写的代码变得非常复杂。

到目前为止,我只发现了一个相对安全的情况。我们有一个容器类,该类采用存储对象的地址。当存储的类具有重载的operator&时,将调用该重载运算符,从而引起问题。

因此,我添加了以下检查:

__if_exists( T::operator& ) {
   static_assert( false );
}

现在,如果类型存储中有一个operator&成员函数,则代码至少不会编译。

我认为这个用例非常清晰易读。

还有哪些情况可以使用__if_exists而不会得到大量难以阅读的代码?


2
和模板中的SFINAE检查一样的东西?我还没有听说过__if_exists,很不错。 - Rup
@Rup:SFINAE能否用于检测特定的成员函数? - Nawaz
2
如果你打算移植到其他平台,我会谨慎使用 __if_exists;我相当确定它是微软特有的。 - Wheatevo
@Nawaz 不知道,我只看到 SFINAE 用于检测模板参数的子类型。但它们都是模板参数的编译时检查,所以我期望它们会有相同的应用。 - Rup
@Nawaz,显然你可以:http://www.ideone.com/gpUU5 - Nim
2个回答

3

虽然我不确定这总是可行或有用的,但在D语言中,__if_exists可以被理解为static if
例如,以下代码将打印b

template< bool > struct static_if_t;
template<> struct static_if_t< true > {};
#define STATIC_IF( c )     __if_exists    ( static_if_t< (c) > )
#define STATIC_UNLESS( c ) __if_not_exists( static_if_t< (c) > )

struct X {
  static bool const v = false;
};

STATIC_IF( X::v ) {
  void f() { puts("a"); }
}
STATIC_UNLESS( X::v ) {
  void f() { puts("b"); }
}

int main() {
  f(); // prints "b"
}

2

我认为您可以使用它来区分联合体和类,因为类有构造函数而联合体没有。

您可能需要在例如boost::type_traits::is_class<T>boost::type_traits::is_union<T>中使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接