带有const引用的std :: remove_const

daf*_*ito 17 c++ templates std c++11

为什么不std::remove_const转换const T&T&?这个公认的相当人为的例子证明了我的问题:

#include <type_traits>

int main()
{
    int a = 42;
    std::remove_const<const int&>::type b(a);

    // This assertion fails
    static_assert(
        !std::is_same<decltype(b), const int&>::value,
        "Why did remove_const not remove const?"
    );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上述情况很容易解决,因此对于上下文,请想象以下内容:

#include <iostream>

template <typename T>
struct Selector
{
    constexpr static const char* value = "default";
};

template <typename T>
struct Selector<T&>
{
    constexpr static const char* value = "reference";
};

template <typename T>
struct Selector<const T&>
{
    constexpr static const char* value = "constref";
};

int main()
{
    std::cout
        << Selector<typename std::remove_const<const int&>::type>::value
        << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我希望reference被展示,而不是constref.

And*_*owl 15

std::remove_const删除顶级 const资格.In const T&,相当于T const&,资格不是顶级的:事实上,它不适用于引用本身(这将是无意义的,因为引用根据定义是不可变的),而是适用于引用的类型.

C++ 11标准第20.9.7.1段中的表52规定了关于std::remove_const:

成员typedef类型应命名相同的类型,T除了已删除任何顶级 const限定符.[ 示例:remove_const<const volatile int>::type评估为 volatile int,而remove_const<const int*>::type评估为const int*.- 结束例子 ]

为了剥离const,您首先必须申请std::remove_reference,然后申请std::remove_const,然后(如果需要)申请std::add_lvalue_reference(或适用于您的情况).

注意:正如Xeo在评论中提到的那样,您可以考虑使用别名模板,例如Unqualified执行前两个步骤,即删除引用,然后去掉const- (和volatile-)限定条件.

  • 前两者通常以“Unqualified&lt;T&gt;”别名分组在一起。 (2认同)