假设我们有两个功能:
//(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)
,但可能还有另一种解决方案吗?
答案 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}}强制第一次重载非文字,但我不知道这是否对你的用例来说会有问题。