繁体   English   中英

enable_if + disable_if组合会引发一个模糊的调用

[英]enable_if + disable_if combination provokes an ambiguous call

在尝试回答这个问题时,我想建议使用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 ...)扼杀了这个:

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来修补它,并且需要一个虚拟的第二个参数...但我仍然对编译器为什么会阻塞它感兴趣。

编译器因为忘记了enable_ifdisable_if上的trailing ::type而被阻塞。 始终定义模板; 当且仅当表达式为true (对于enable_if )或为false (对于disable_if )时,才存在成员type

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); }

如果没有trailing ::type ,则函数模板只会创建重载,这些重载将指向enable_ifdisable_if实例的指针作为第二个参数。 使用trailing ::type ,模板要么使用void*类型的第二个参数创建重载,要么删除重载(即所需的行为)。

使用“return type”版本的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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM