Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using decltype to choose function specialization

Tags:

c++

templates

I wonder why in my example I cant use decltype specifier to choose a specializated template method.

The code works as expected only if I use declared template parameter to point specialization:

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);
}

As expected, the specialization of function for strings is called once for string argument.

But when I use decltype to determine the type of the first parameter, the specialized function for strings is not called, the generic one is being choosed :

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);
}

I wonder why when using decltype specifier, the specialization for strings is not called? decltype should return const std::string& type as far as I know.

like image 966
Sielan Avatar asked Jul 20 '26 10:07

Sielan


1 Answers

decltype(first) will yield std::string const & while function is specialized for case when T is std::string. This can be fixed by doropping cv qualifier and reference:

return sum<::std::remove_const_t<::std::remove_reference_t<decltype(first)>>>(first) + sumBytes(tail...);
like image 156
user7860670 Avatar answered Jul 23 '26 04:07

user7860670



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!