带有常量引用的 std::remove_const [英] std::remove_const with const references

查看:26
本文介绍了带有常量引用的 std::remove_const的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Why does std::remove_const not convert const T& to T&? This admittedly rather contrived example demonstrates my question:

#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;
}

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

The above case is trivially easy to fix, so for context, imagine the following:

#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;
}

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

In the above example, I'd expect reference to be shown, rather than constref.

推荐答案

std::remove_const 移除了顶级 const-qualifications.在 const T& 中,等同于 T const&,限定不是顶级的:实际上,它不适用于引用本身(即没有意义,因为根据定义,引用是不可变的),而是针对被引用的类型.

std::remove_const removes top level const-qualifications. In const T&, which is equivalent to T const&, the qualification is not top-level: in fact, it does not apply to the reference itself (that would be meaningless, because references are immutable by definition), but to the referenced type.

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

Table 52 in Paragraph 20.9.7.1 of the C++11 Standard specifies, regarding std::remove_const:

成员 typedef 类型应命名为与 T 相同的类型,除了任何顶级常量限定符已被删除.[ 示例:remove_const::type 计算结果为volatile int,而 remove_const::type 计算const int*.— 结束示例 ]

The member typedef type shall name the same type as T except that any top-level const-qualifier has been removed. [ Example: remove_const<const volatile int>::type evaluates to volatile int, whereas remove_const<const int*>::type evaluates to const int*. — end example ]

为了去掉const,你首先要应用std::remove_reference然后应用std::remove_const,然后(如果需要)应用 std::add_lvalue_reference(或任何适合您的情况).

In order to strip const away, you first have to apply std::remove_reference, then apply std::remove_const, and then (if desired) apply std::add_lvalue_reference (or whatever is appropriate in your case).

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

NOTE: As Xeo mentions in the comment, you may consider using an alias template such as Unqualified to perform the first two steps, i.e. strip away the reference, then strip away the const- (and volatile-) qualification.

这篇关于带有常量引用的 std::remove_const的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆