Почему компилятор не выбирает мою перегрузку шаблона функции в следующем примере?

Секрет поиска чего-либо в Google заключается в том, чтобы ввести комбинацию поисковых терминов (или цитируемых фраз), которые, скорее всего, будут в контенте, который вы ищете, но вряд ли будут появляться вместе в несвязанном контенте. Подстановочное выражение делает противоположность этому. Просто введите условия, которые, как вы ожидаете, будут совпадать с подстановочным знаком, имея в виду, что Google подойдет для вас. В те времена, когда компьютеры работали на парах, Lycos (iirc) сопоставлял шаблоны, но они отключили его несколько лет назад. Я полагаю, это слишком сильно загружало их серверы.

5
задан Steve Guidi 29 March 2013 в 17:13
поделиться

3 ответа

Вы можете сделать это:

f(v, static_cast<Base*>(&derived));

Или использовать SFINAE, чтобы удалить первую функцию в качестве кандидата на выбор:

// Install boost library and add these headers:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>

// #1 - change it to look like this (note the keyword void changed positions)
template <typename T1, typename T2>
typename boost::disable_if<
   typename boost::is_convertible<T2, Base*>, void>::type
f(const T1& a, const T2& b)
{
};

// #2 - this one can stay the same
template <typename T1, typename T2>
void f(const std::vector<std::pair<T1, T2> >& v, Base* p)
{
};
12
ответ дан 18 December 2019 в 07:30
поделиться

Учитывая, что второй параметр f является производным типом от Base

, он может быть преобразован в такой, но является производным *. Первая шаблонная функция не требует преобразований, а вторая требует преобразований, поэтому выбирает первую.

Это выбирает вторую:

f(v, static_cast<Base*>(&derived));

Кстати, main возвращает int .

8
ответ дан 18 December 2019 в 07:30
поделиться

Помимо очевидных тем о Koenig Lookup , более или менее хорошо реализованных компиляторами (особенно старые, довольно проблематичные), есть несколько подводных камней, касающихся специализация шаблона .

Специализация требует, чтобы типы точно совпадали (не знаю, как это определяет стандартное выражение, но по моему опыту [gcc, msvc] производный класс не будет сопоставлен). Если вы добавите некрасивое приведение к Base *, оно должно работать так, как вы предполагаете, при желании можно добавить еще одну специализацию для Derived ...

1
ответ дан 18 December 2019 в 07:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: