Ответ Jarod42 только частично применим к моей ситуации.
Есть две вещи, которые я не осознавал:
- Специализация шаблона функции должна возвращать тот же тип, что и базовый вариант.
Точный способ определения типа возвращаемого значения не имеет значения. Итак, вместо определения, предложенного Джародом 42
template <>
std::enable_if_t<!is_detected<detect_size, TCollection>::value, size_t >
size<TCollection>(const TCollection& c) { return c.GetSize(); }
достаточно написать
template <>
size_t size(const TCollection& c) { return c.GetSize(); }
- Перегрузка не будет работать, если ее определение появится после вызова функции.
Если код структурирован так:
template <typename T>
size_t size(const T& x) { return x.size(); }
template <typename T>
std::vector<int> reserve_same_number_of_ints(const T& x) {
std::vector<int> vec;
vec.reserve(size(x));
return vec;
}
/* specialize or overload here for special_type */
/* call reserve_same_number_of_ints on the special_type */
Специализация шаблона выбрана, но перегрузка отсутствует.