Использование decltype для выбора специализации функции - PullRequest
3 голосов
/ 11 мая 2019

Интересно, почему в моем примере я не могу использовать спецификатор decltype для выбора специализированного метода шаблона.

Код работает как положено, только если я использую объявленный параметр шаблона для указания специализации:

template <typename T>
auto sum(const T& value)
{
    std::cout << "sum for template" << std::endl;
    return sizeof(value);   
}

template<>
auto sum(std::string const& value)
{
    std::cout << "sum for string" << std::endl;
    return value.length();
}

template <typename Last>
auto sumBytes(const Last& last)
{
    return sum<Last>(last);
}


template <typename First, typename ...Tail>
auto sumBytes(const First& first, const Tail& ...tail)
{
    return sum<First>(first) + sumBytes(tail...);
}

int main()
{
    std::string str = "hello";
    auto sum = sumBytes(str,2,3,4);
}

Как и ожидалось, специализация функции для строк вызывается один раз для строкового аргумента.

Но когда я использую decltype для определения типа первого параметра, специализированная функция для строк не вызывается, а выбирается общая:

template <typename T>
auto sum(const T& value)
{
    std::cout << "sum for template" << std::endl;
    return sizeof(value);   
}

template<>
auto sum(std::string const& value)
{
    std::cout << "sum for string" << std::endl;
    return value.length();
}

template <typename Last>
auto sumBytes(const Last& last)
{
    return sum<decltype(last)>(last);
}


template <typename First, typename ...Tail>
auto sumBytes(const First& first, const Tail& ...tail)
{
    return sum<decltype(first)>(first) + sumBytes(tail...);
}

int main()
{
    std::string str = "hello";
    auto sum = sumBytes(str,2,3,4);
}

Интересно, почему при использовании спецификатора decltype специализация для строк не вызывается? decltype должен вернуть const std::string& тип, насколько я знаю.

1 Ответ

2 голосов
/ 11 мая 2019

decltype(first) даст std::string const &, тогда как функция специализирована для случая, когда T равно std::string. Это можно исправить с помощью doropping cv qualifier и ссылки:

return sum<::std::remove_const_t<::std::remove_reference_t<decltype(first)>>>(first) + sumBytes(tail...);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...