При попытке ответить на этот вопрос я хотел предложить использовать enable_if
+ disable_if
, чтобы разрешить перегрузку метод, основанный на том факте, что тип был (или нет) полиморфным.
Итак, я создал небольшой тестовый файл:
template
void* address_of(T* p,
boost::enable_if< boost::is_polymorphic >* dummy = 0)
{ return dynamic_cast(p); }
template
void* address_of(T* p,
boost::disable_if< boost::is_polymorphic >* dummy = 0)
{ return static_cast(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
[с T = N], void> *)
test.cpp: 20: примечание:void * address_of (T *, boost :: disable_if
[с T = N], void> *)
Моему человеческому разуму кажется довольно ясным, какую перегрузку следует использовать здесь. Я имею в виду, что кажется ясным, что я определил альтернативу, и одновременно можно использовать только одну функцию ... и я бы подумал, что SFINAE позаботится о недопустимости ненужной перегрузки.
Я исправил это с помощью ...
(многоточие) вместо disable_if
и требующий фиктивного второго аргумента ... но мне все еще интересно, почему компилятор подавился этим.