Пытаясь ответить на этот вопрос Я хотел предложить использовать 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
и требуя фиктивного второго аргумента ... но мне все еще интересно, почему компилятор подавился этим.