为什么在从通用引用推导类型时忽略 const?
Why const is ignored when deducing type from universal reference?
这是我的 A class 的定义并为其创建函数:
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 左值传递给 make_a
函数时,我希望实例化的 class 类似于
class B
{
public:
B( int &test )
: _test( test )
{}
public:
const int &_test;
};
但是A::_test
的类型被推断为int&
而不是const int&
:
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 默认编译器。
谢谢。
此行为是由语言标准引起的。
N4140 §8.3.2 [dcl.ref]/1
Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name (7.1.3, 14.1) or
decltype-specifier (7.1.6.2), in which case the cv-qualifiers are ignored. [ Example:
typedef int& A;
const A aref = 3; // ill-formed; lvalue reference to non-const initialized with rvalue
The type of aref
is “lvalue reference to int
”, not “lvalue
reference to const int
”. —end example ]
这是我的 A class 的定义并为其创建函数:
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 左值传递给 make_a
函数时,我希望实例化的 class 类似于
class B
{
public:
B( int &test )
: _test( test )
{}
public:
const int &_test;
};
但是A::_test
的类型被推断为int&
而不是const int&
:
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 默认编译器。
谢谢。
此行为是由语言标准引起的。
N4140 §8.3.2 [dcl.ref]/1
Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name (7.1.3, 14.1) or decltype-specifier (7.1.6.2), in which case the cv-qualifiers are ignored. [ Example:
typedef int& A; const A aref = 3; // ill-formed; lvalue reference to non-const initialized with rvalue
The type of
aref
is “lvalue reference toint
”, not “lvalue reference toconst int
”. —end example ]