为什么std :: remove_const没有删除const限定符?

NoS*_*tAl 21 c++ const decltype type-traits c++11

请注意,我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 
}
Run Code Online (Sandbox Code Playgroud)

似乎remove_const<deref>::typeconst int,不像int我期望的那样可变.

son*_*yao 30

注意,*first是左值表达,然后的结果类型decltype(*first)将是const int&,即一个参考const int.引用const本身不是(它不能是const限定的,没有这样的东西int& const),使用std::remove_const它会产生相同的类型,即const int&.

请参见decltype说明符:

3)如果参数是任何其他类型的表达式T,和

b)如果表达式的值类别是左值,则decltype产生 T&;

你可以使用std::remove_conststd::remove_reference在一起:

std::remove_const<std::remove_reference<deref>::type>::type // -> int
                                        ~~~~~               // -> const int &
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~        // -> const int
Run Code Online (Sandbox Code Playgroud)

BTW:

请注意,我std::thread只是用来获取错误中的可读类型:

请注意,它没有为这种情况提供正确的类型.这是来自Effective Modern C++(Scott Meyers)的类模板助手:

template<typename T>
class TD;
Run Code Online (Sandbox Code Playgroud)

并用它作为

TD<deref> td;
Run Code Online (Sandbox Code Playgroud)

您将收到包含类型的错误消息deref,例如来自clang:

prog.cc:16:11: error: implicit instantiation of undefined template 'TD<const int &>'
TD<deref> td;
          ^
Run Code Online (Sandbox Code Playgroud)

  • Aaaand这就是为什么你应该写`int const&`而不是`const int&`...然后问题的答案是显而易见的. (3认同)