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