enable_if + disable_if组合引起一个模棱两可的呼叫
题
试图回答 这个问题 我想建议使用 enable_if
+ disable_if
基于类型是(或不是)多态性的事实,可以使方法过载。
因此,我创建了一个小测试文件:
template <class T>
void* address_of(T* p,
boost::enable_if< boost::is_polymorphic<T> >* dummy = 0)
{ return dynamic_cast<void*>(p); }
template <class T>
void* address_of(T* p,
boost::disable_if< boost::is_polymorphic<T> >* dummy = 0)
{ return static_cast<void*>(p); }
struct N { int x; };
int main(int argc, char* argv[])
{
N n;
std::cout << address_of(&n) << std::endl;
return 0;
}
这似乎很驯服。
但是GCC(3.4 ...)cho缩于此:
test.cpp:功能
int main(int, char**)
:
test.cpp:29:错误:超载的呼叫address_of(N*)
是模棱两可的
test.cpp:17:注意:候选人是:void* address_of(T*, boost::enable_if<boost::is_polymorphic<T>, void>*)
t = n
test.cpp:20:注意:void* address_of(T*, boost::disable_if<boost::is_polymorphic<T>, void>*)
t = n
在我的脑海看来,这里应该使用哪种超负荷。我的意思是,很明显,我已经定义了一种替代方案,并且一次只能使用一个函数……而且我认为Sfinae会照顾不必要的过载。
我通过使用 ...
(省略号)而不是 disable_if
并需要一个虚拟的第二个论点...但是我仍然对编译器为何cho之以鼻仍然感兴趣。
解决方案
编译器被cho住了,因为您忘记了尾声 ::type
在 enable_if
和 disable_if
. 。模板总是定义的;只是成员 type
存在时,只有当表达式为 true
(为了 enable_if
) 或者 false
(为了 disable_if
).
template <class T>
void* address_of(T* p,
打字 boost::enable_if< boost::is_polymorphic<T> >::类型* dummy = 0)
{ return dynamic_cast<void*>(p); }
template <class T>
void* address_of(T* p,
打字 boost::disable_if< boost::is_polymorphic<T> >::类型* dummy = 0)
{ return static_cast<void*>(p); }
没有落后 ::type
, ,您的功能模板只会创建过载,这些超载将指针带到实例 enable_if
或者 disable_if
作为第二个参数。带有尾随 ::type
, ,模板要么创建一个具有类型的第二个参数的过载 void*
, ,或删除过载(即所需的行为)。
其他提示
使用enable_if的“返回类型”版本在3.4.4中工作: gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <iostream>
template <class T>
typename boost::enable_if< boost::is_polymorphic<T>, void* >::type
address_of(T* p)
{ return dynamic_cast<void*>(p); }
template <class T>
typename boost::disable_if< boost::is_polymorphic<T>, void* >::type
address_of(T* p)
{ return static_cast<void*>(p); }
struct N { int x; };
int main(int argc, char* argv[])
{
N n;
std::cout << address_of(&n) << std::endl;
return 0;
}