理想情况下,我们可以使用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>();
}
这就是imho,使用它的最好方法。
然而,由于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部分找到一个更好的解决方法。
答案 0 :(得分: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;}