Подтвердить что ты не робот

Почему std:: remove_const удаляет конструктор const?

Обратите внимание, что я использую std::thread только для получения читаемых типов в ошибках:

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 
}

Кажется, что remove_const<deref>::type есть const int, а не изменяет int, как я ожидал.

4b9b3361

Ответ 1

Обратите внимание, что *first является выражением lvalue, тогда тип результата decltype(*first) будет const int&, то есть ссылка на const int. Ссылка не сама const (она не может быть const-qualified, нет такой вещи, как int& const), используя std::remove_const на ней будет выдавать один и тот же тип, т.е. const int&.

См. спецификатор decltype:

3) Если аргументом является любое другое выражение типа T, а

b), если категория значений выражения lvalue, то decltype дает T&;

Вы можете использовать std::remove_const вместе с std::remove_reference:

std::remove_const<std::remove_reference<deref>::type>::type // -> int
                                        ~~~~~               // -> const int &
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~        // -> const int

BTW:

Обратите внимание, что я использую std::thread только для получения читаемых типов в ошибках:

Обратите внимание, что это не дает правильный тип для этого случая. Здесь помощник шаблона класса для этого из Эффективный современный С++ (Scott Meyers):

template<typename T>
class TD;

и использовать его как

TD<deref> td;

Вы получите сообщение об ошибке, содержащее тип deref, например. из clang:

prog.cc:16:11: error: implicit instantiation of undefined template 'TD<const int &>'
TD<deref> td;
          ^