有没有什么方法可以实现像std :: is_integral_literal这样的东西?

时间:2017-03-20 14:48:49

标签: c++ typetraits

假设我们有两个功能:

//(1)
template<class T ,
         class = typename std::enable_if<std::is_integral<T>::value & ! is_integral_literal<T>::value>::type >
void foo(T)
{
}

//(2)
template<class T ,
         class = typename std::enable_if<is_integral_literal<T>::value>::type >
void foo(const T&)
{
}

所以

int x;
foo(x); //calls (1)
foo(0); //calls (2)
foo(1000); //calls (2)

如何实施is_integral_literal?我已经使用operator "" _int_lit(long long)做了一些解决方法,这使我有能力表达它 foo(0_int_lit),但可能还有另一种解决方案吗?

1 个答案:

答案 0 :(得分:3)

一种方法可能是使用整数文字是右值这一事实?如果你的功能签名是

int

当使用右值T(如文字)调用时,int将被推断为普通int i = 0; f(i); ,enable_if条件将保持,并且将考虑此重载。但是当用左值调用时,例如

T

然后int&将被推断为is_integral<int&>::value,在这种情况下template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>> T f(const T& t) { return t; } 为假,SFINAE将启动。然后您可以添加第二个重载,如

f(std::move(i))

处理左值情况(当使用右值调用时,将考虑两个重载,但第一个将是更好的匹配)。

这完全不符合完全法案,因为仍然可以通过调用{{1}}强制第一次重载非文字,但我不知道这是否对你的用例来说会有问题。