Question

I have the following c++11-code:

#include <iostream>
#include <type_traits>

template<typename T> void overload(T&& t);
template<> void overload<char&>(char& t) { std::cout << "char& called" << std::endl; }
template<> void overload<const char&>(const char& t) { std::cout << "const char& called" << std::endl; }

int main() {

    std::cout << "const char: " << ((std::is_const<const char>::value)?"const":"non-const") << std::endl;
    std::cout << "const char&: " << ((std::is_const<const char&>::value)?"const":"non-const") << std::endl;

    const char c = 'c';
    overload(c);

    return 0;
}

When running I get

const char: const
const char&: non-const
const char& called

I'm wondering why the second call to std::is_const does not see the constness whereas the call to overload does see it.

Any Thoughts?

This question is highly related to this one: Type deduction in templated functions and const quailifier but still a bit different.

Was it helpful?

Solution

You seem to confuse levels of constness.

is_const correctly reports that the type lacks the top-level const (const char&const would be true if legal).

Your overload matches the correct function on constness left to &.

Try the same thing with pointers, char*, const char*, char* const and const char*const to see the levels better.

OTHER TIPS

What has to be said about top-level const has been said in the comments and other answer. How you get what you probably would like to see: use std::remove_reference

std::is_const<std::remove_reference<const char&>::type>::value
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top