[英]Why Type Traits is not working inside namespace (std::enable_if) - c++11
If the following code is placed inside a namespace then its not working, but without namespace its working fine... 如果将以下代码放置在命名空间中,则它将无法正常工作,但是如果没有命名空间,它将无法正常工作...
template <typename T,typename _F>
inline typename std::enable_if< is_iterable<T>::value >::type
for_all_ele(T&& arr,_F&& fn)
{
for(auto &x:arr)
for_all_ele(x,fn);
}
template <typename T,typename _F>
inline typename std::enable_if< not is_iterable<T>::value >::type
for_all_ele(T&& x,_F&& fn)
{
fn(x);
}
is_iterable is defined over it... is_iterable是在上面定义的...
The full code is here : http://ideone.com/goJ0Zf 完整的代码在这里: http : //ideone.com/goJ0Zf
Till now all I can find is the template specialization of 'for_all_ele' for scalar data is not being detected inside namespace... 直到现在我能找到的是'for_all_ele'的模板特化,因为在名称空间中没有检测到标量数据...
Your recursion works when it is found via Koenig Lookup (aka ADL, aka Argument Dependent Lookup) and not when it is not found that way. 通过Koenig查找(又名ADL,又称自变量依赖查找)找到您的递归,而不是通过这种方式找不到它。
This call: 这个电话:
{
for(auto &x:arr)
for_all_ele(x,fn);
}
does not see the later declared for_all_ele
, unless one of x
or fn
finds it via ADL. 不会看到后来声明的for_all_ele
, 除非 x
或fn
之一通过ADL找到了它。 As it happens, when it isn't in a namespace, the lambda you pass as fn
is in the same (root) namespace as your for_all_ele
function is. 碰巧的是,当它不在名称空间中时,以fn
身份传递的lambda与for_all_ele
函数位于相同的(根)名称空间中。 So it is found. 这样就找到了。
When for_all_ele
is in a namespace, it doesn't work, because the lambda is in a different namespace. 当for_all_ele
在名称空间中时,它不起作用,因为lambda在其他名称空间中。
There are three approaches. 有三种方法。
First, you can forward-declare it. 首先,您可以向前声明它。
Second, you can create a wrapping function. 其次,您可以创建包装功能。 It then instantiates a toy type ( struct toy_tag{};
) and passes it together with the other arguments to the for_all_ele_impl
, which pass said toy_tag
when they recurse. 然后,它实例化玩具类型( struct toy_tag{};
)并将其与其他参数一起传递给for_all_ele_impl
,后者在递归时将其传递给所述toy_tag
。
Third, you can simply move the recursive case after the terminating case: https://ideone.com/17h75Q 第三,您可以简单地将递归条件移到终止条件之后: https : //ideone.com/17h75Q
template <class T, class F>
inline typename std::enable_if< is_iterable<T>::value >::type
for_all_ele(T&& arr,F&& f)
{
for(auto&&x:arr)
for_all_ele(decltype(x)(x),f);
}
template <class T, class F>
inline typename std::enable_if<
!is_iterable<T>::value
>::type
for_all_ele(T&& t,F&& f) {
std::forward<F>(f)(std::forward<T>(t));
}
I renamed your _F
to F
, as the name _F
is reserved by the standard in all contexts. 我将您的_F
重命名为F
,因为标准在所有情况下都保留名称_F
。 I also perfect forwarded the function object, because I'm like that. 我也很完美地转发了函数对象,因为那样。 And I did some perfect forwarding your code was missing. 我做了一些完美的转发,您的代码丢失了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.