Note that I use std::thread just to get readable types in the errors:
int main() {
    const int * first;
    using deref = decltype(*first);
    std::thread s = std::remove_const<deref>::type{}; // const int ???
    std::thread s2 = deref{}; // const int
    std::thread s3 = std::remove_const<const int>::type{}; // int 
}
It seems as if remove_const<deref>::type is const int, not mutable int as I would expect.
Note that *first is an lvalue expression, then the result type of decltype(*first) would be const int&, i.e. a reference to const int. The reference is not const itself (it can't be const-qualified, there's no such thing like int& const), using std::remove_const on it will yield the same type, i.e. const int&.
See decltype specifier:
- If the argument is any other expression of type
 T, andb) if the value category of expression is lvalue, then
decltypeyieldsT&;
You could use std::remove_const with std::remove_reference together:
std::remove_const<std::remove_reference<deref>::type>::type // -> int
                                        ^^^^^               // -> const int &
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        // -> const int
BTW:
Note that I use
std::threadjust to get readable types in the errors:
Note that it doesn't give the correct type for this case. Here's a class template helper for this from the Effective Modern C++ (Scott Meyers):
template<typename T>
class TD;
and use it as
TD<deref> td;
You'll get the error message containing the type of deref, e.g. from clang:
prog.cc:16:11: error: implicit instantiation of undefined template 'TD<const int &>'
TD<deref> td;
          ^
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With