【问题标题】:Is there a nicer workaround for enable_if bug in CLang (Bug 11723)?CLang 中的 enable_if 错误是否有更好的解决方法(错误 11723)?
【发布时间】:2014-08-18 17:33:14
【问题描述】:

理想情况下,我们可以用 enable_if 做类似的事情:

#include <type_traits>

namespace detail {
    enum class enabler_t { DUMMY };
}

template<bool B>
using enable_if_u = typename std::enable_if<B, detail::enabler_t>::type;

template<bool B>
using disable_if_u = typename std::enable_if<!B, detail::enabler_t>::type;

template<typename T, enable_if_u<std::is_same<T, int>::value>...>
int a(){return 0;}

template<typename T, disable_if_u<std::is_same<T, int>::value>...>
double a(){return 0.0;}

int main() {
    auto x = a<int>();
}

恕我直言,这是最好的使用方式。

但是,由于bug 11723,这不适用于 Clang。

我正在使用的解决方法是使用虚拟 constexpr 变量:

namespace detail {
    enum class enabler_t { DUMMY };
    constexpr const enabler_t dummy = enabler_t::DUMMY;
}

//...

template<typename T, enable_if_u<std::is_same<T, int>::value> = detail::dummy>
int a(){return 0;}

template<typename T, disable_if_u<std::is_same<T, int>::value> = detail::dummy>
double a(){return 0.0;}

//...

我不是这种解决方法的忠实拥护者,我想知道是否还有另一种解决方法可以使代码在 Clang 中工作?我正在寻找一个纯 C++ 解决方案,不涉及预处理器。

这个例子本身只是为了说明问题,它根本没有用,还有很多方法可以让它变得更好。我只想为 enable_if 部分找到更好的解决方法。

【问题讨论】:

  • 您只想在T = int 时调用第一个a,否则调用第二个aT 是否应该是任何示例中的参数包?
  • 为什么不直接使用a single, defaulted non-type template parameter 或者标签调度?
  • @dyp 我意识到,我只是想知道是否打算在具有不同返回类型的两个函数之间切换。正如您自己刚刚演示的那样,有更简单的方法可以做到这一点。
  • @Praetorian 至少 g++(以及我对标准的阅读)是这样解释它的。
  • @dyp “为什么……” - 因为 OP 的方式是 less syntactic clutter

标签: c++ templates c++11 clang sfinae


【解决方案1】:

您应该只使用宏:

#define ENABLE_IF(...) typename std::enable_if<(__VA_ARGS__), detail::enabler_t>::type=detail::enabler_t::DUMMY

宏还具有避免 C++ 中最麻烦的解析的优点,因为它总是可以在布尔表达式周围放置括号。如果你觉得大写宏看起来很难看,你可以使用ZLang 让它更干净,如下所示:

#define BW_ENABLE_IF(...) typename std::enable_if<(__VA_ARGS__), detail::enabler_t>::type=detail::enabler_t::DUMMY
#define ZLANG_bw_enable_if (BW_ENABLE_IF)

那么如果用-DZLANG_NS=bw编译就可以写如下:

template<typename T, $(enable_if std::is_same<T, int>())>
int a(){return 0;}

【讨论】:

  • 很好的解决方案,但我宁愿尽可能避免使用宏,感觉不太像 C++。
  • 我最终还是使用了宏,所以这个答案是最好的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
  • 2018-06-24
  • 1970-01-01
  • 2011-11-03
  • 1970-01-01
相关资源
最近更新 更多