enable_if + disable_if组合引起模糊调用 [英] enable_if + disable_if combination provokes an ambiguous call
问题描述
在尝试回答此问题时,我想要建议使用 enable_if
+ disable_if
允许基于类型为(或不是)多态性。
While trying to answer this question I wanted to suggest the use of enable_if
+ disable_if
to allow the overload of a method based on the fact that a type was (or not) polymorphic.
所以我创建了一个小测试文件:
So I created a small test file:
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 ...)choke on this:
However gcc (3.4 ...) choke on this:
test.cpp:在函数
int main(int,char **)
:
test.cpp:29:error:call of overloadedaddress_of(N *)
不明确
test.cpp:17:注意:候选者是:void * address_of(T *,
[with T = N]
boost :: enable_if< boost :: is_polymorphic< T>,void> *)
test.cpp:20:note:void * address_of(T *,
[with T = N]
boost :: disable_if< boost :: is_polymorphic&T; gt,void> *)
test.cpp: In function
int main(int, char**)
:
test.cpp:29: error: call of overloadedaddress_of(N*)
is ambiguous
test.cpp:17: note: candidates are:void* address_of(T*, boost::enable_if<boost::is_polymorphic<T>, void>*)
[with T = N]
test.cpp:20: note:void* address_of(T*, boost::disable_if<boost::is_polymorphic<T>, void>*)
[with T = N]
我的人类思想看起来很清楚,这里应该使用过载。我的意思是,似乎很清楚,我已经定义了一个替代,只有一个功能可以一次使用...我会认为SFINAE将照顾无效的不必要的重载。
It seems rather clear to my human mind which overload should be used here. I mean it seems clear that I have defined an alternative and only one function can be used at a time... and I would have thought that SFINAE would take care of invalidating the unnecessary overload.
我使用 ...
(省略号)而不是 disable_if
I patched it up by using ...
(ellipsis) instead of disable_if
and requiring a dummy second argument... but I am still interested in why the compiler choke on this.
推荐答案
编译器因为忘记了第二个参数而感到厌烦。在 enable_if
和 disable_if
上尾随 :: type
。模板总是定义的;它只是当且仅当表达式 true
()时才存在成员
)或 type
> enable_if false
(用于 disable_if
)。
The compiler choked because you forgot the trailing ::type
on enable_if
and disable_if
. The templates are always defined; it is just that the member type
is present if and only if the expression is true
(for enable_if
) or false
(for disable_if
).
template <class T>
void* address_of(T* p,
typename boost::enable_if< boost::is_polymorphic<T> >::type* dummy = 0)
{ return dynamic_cast<void*>(p); }
template <class T>
void* address_of(T* p,
typename boost::disable_if< boost::is_polymorphic<T> >::type* dummy = 0)
{ return static_cast<void*>(p); }
没有尾随 :: type
你的函数模板只是创建重载,它接受指向 enable_if
或 disable_if
实例的指针作为第二个参数。使用后面的 :: type
,模板将创建一个重载类型为 void *
的第二个参数重载被删除(即期望的行为)。
Without the trailing ::type
, your function templates just create overloads that take pointers to instances of enable_if
or disable_if
as the second parameter. With the trailing ::type
, the templates either create an overload with a second parameter of type void*
, or the overload is removed (i.e. the desired behaviour).
这篇关于enable_if + disable_if组合引起模糊调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!