【问题标题】:std::remove_const with const references带有 const 引用的 std::remove_const
【发布时间】:2013-04-08 19:19:21
【问题描述】:

为什么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;
}

上面的情况很容易解决,所以对于上下文,想象一下:

#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

【问题讨论】:

  • 记住,没有 const 引用,只有 const 引用。

标签: c++ templates c++11 std


【解决方案1】:

std::remove_const 删除 顶级 const-qualifications。在等同于const T&amp;const T&amp; 中,限定条件不是顶级的:实际上,它并不适用于引用本身(那将毫无意义,因为引用在定义上是不可变的),而是适用于被引用的输入。

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

成员 typedef 类型应命名为与T 相同的类型,除了 任何 顶级 const-qualifier 已被删除。 [示例remove_const&lt;const volatile int&gt;::type 计算结果为 volatile int,而 remove_const&lt;const int*&gt;::type 评估 到const int*。 — 结束示例 ]

为了去除const,您首先必须应用std::remove_reference然后应用std::remove_const,然后(如果需要)应用std::add_lvalue_reference(或任何适用于你的情况)。

注意:正如Xeo 在评论中提到的,您可以考虑using an alias template such as Unqualified 执行前两个步骤,即剥离引用,然后剥离const-(和volatile-) 资格。

【讨论】:

  • 前两个通常在Unqualified&lt;T&gt; 别名下组合在一起。
  • 啊,我明白了。非常感谢您的解释。 :)
  • @dafrito:很高兴它有帮助:)
  • 这里举个例子说明如何组合它们。
猜你喜欢
  • 2017-09-13
  • 2021-09-25
  • 1970-01-01
  • 2012-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多