2016-11-12 2 views
3

は私のクラスの定義であり、そのための機能を作る:私はint型左辺値make_aに関数を渡すとき汎用参照から型を推測する際にconstが無視されるのはなぜですか?ここ

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

、私はインスタンス化されたクラスは

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のデフォルトコンパイラを使用しています。

ありがとうございました。

+1

ため 'のconst add_lvalue_reference_t ' INT&あります。 –

+3

'const int&'では、 'int'はconstであり、参照ではありません。これは 'const int'への参照であり、' 'int''へのconst参照ではありません。しかし 'cons T'では' T'の 'const'であり、' T'のサブタイプではありません。 'T 'が参照型であるとき、' const T'は 'const参照'を意味しますが、それはノーオペレーションです。参照は、ある意味では常に 'const'です(初期化されると、参照する内容を変更することはできません)。 –

+1

'T'が' int * 'だった場合、' const T'は 'int * const'(非const' int'へのconstポインタ)になります。これはまったく同じではありません'const int *'別名int const * '(const' int'への非constポインタ)。 –

答えて

1

この現象は、言語標準によって発生します。

N4140§8.3.2[dcl.ref]/1

CV-修飾参照は、CV-修飾子をのtypedef名(7.1の使用を介して導入されている場合を除き、病気に形成されています.3、14.1)または decltype-specifier(7.1.6.2)この場合、cv-qualifierは無視されます。 [例:aref

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

タイプが「intを左辺値参照」ではなく「const intに左辺値 参照」です。 - 端例]

関連する問題