【问题标题】:Why const is ignored when deducing type from universal reference?为什么从通用引用推断类型时忽略 const?
【发布时间】:2016-11-12 22:04:58
【问题描述】:

这是我的 A 类的定义并为它创建函数:

template< typename T >
class A
{
public:
    A( T test )
    : _test( test )
    {}

public:
    const T _test;
};

template <typename T>
A<T> make_a (T&& elem) {
    return A<T>{std::forward<T>(elem)};
}

当我将 int lvalue 传递给make_a 函数时,我希望实例化的类类似于

class B
{
public:
    B( int &test )
    : _test( test )
    {}

public:
    const int &_test;
};

但是A::_test的类型推导出为int&amp;而不是const int&amp;

int main(int argc, const char * argv[]) {

    int a = 1;
    auto aa = make_a(a);
    aa._test = 2; // compiled OK

    B bb(a);
    bb._test = 2; // compilation error
    return 0;
}

谁能解释一下导致这种行为的原因?

我正在使用 XCode 7.0、LLVM 7.0 默认编译器。

谢谢。

【问题讨论】:

  • 因为const add_lvalue_reference_t&lt;int&gt;int&amp;
  • const int&amp; 中,int 是常量,而不是引用。这是对const int 的引用,而不是“对int 的常量引用”。但在cons T 中,Tconst,而不是T 的某个子类型。当T 是引用类型时,const T 表示“常量引用”——但这是一个空操作;从某种意义上说,引用总是const(一旦初始化,您就无法更改它所指的内容)。
  • 另一种看待它的方式:如果 Tint*const T 将是 int* const(指向非 const int 的 const 指针),这根本不是与const int* aka int const* 相同(指向 const int 的非常量指针)。
  • @IgorTandetnik 答案应该张贴在下面的大文本区域!! :-)

标签: c++ templates perfect-forwarding type-deduction


【解决方案1】:

此行为是由语言标准引起的。

N4140 §8.3.2 [dcl.ref]/1

Cv 限定的引用格式错误,除非通过使用 typedef-name (7.1.3, 14.1) 或 decltype-specifier (7.1.6.2),在这种情况下忽略 cv 限定符。 [ 例子:

typedef int& A;
const A aref = 3; // ill-formed; lvalue reference to non-const initialized with rvalue

aref 的类型是“对int 的左值引用”,而不是“左值” 参考const int”。 —结束示例 ]

【讨论】:

    猜你喜欢
    • 2021-11-04
    • 2020-05-05
    • 1970-01-01
    • 2012-10-27
    • 1970-01-01
    • 2012-08-09
    • 2019-11-25
    • 2018-01-29
    • 1970-01-01
    相关资源
    最近更新 更多