Here is the definition of my A class and make function for it:
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)};
}
When I pass int lvalue to make_a
function, I expect the instantiated class to be similar to
class B
{
public:
B( int &test )
: _test( test )
{}
public:
const int &_test;
};
But the type of A::_test
is deduced to be int&
instead of 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;
}
Can anybody explain me what causes such behaviour?
I'm using XCode 7.0, LLVM 7.0 default compiler.
Thanks.
This behaviour is caused by the language standard.
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 ]