2013-05-22 6 views
8

コード例をから取得され:どのようにして、constの一時関数はconst以外のメンバ関数をconst関数よりも呼び出したいのですか?

struct foo 
{ 
    void m() { std::cout << "Non-cv\n"; } 
    void m() const { std::cout << "Const\n"; } 
}; 

template<class T> 
void call_m() 
{ 
    T().m(); 
} 

int main() 
{ 
    call_m<foo>(); 
    call_m<const foo>(); //here 
} 

(私は少し変更された)、出力があるhttp://en.cppreference.com/w/cpp/types/add_cv :2番目の呼び出しで

Non-cv 
Non-cv 

TはCONST修飾されているので、T()あるべきconstバージョンを呼び出してください。または私が逃したいくつかの特別なルールがありますか?

+3

g ++ - 4.8とclang ++ - 3.2がconst関数を呼び出すため、MSVCのバグのように見えます。 – ForEveR

+0

これは以前に起きたバグです。 MSVCは 'T()'の 'T'のconst修飾子を無視します。 –

+1

言語の文言では、テンプレートの中で、 'T'が**非クラス**型で可能なconst-volatile修飾がある場合、* prvalue *を生成するときに修飾が削除される必要があります。それは、VSがクラスの型についても同じロジックを使用しているようです(間違って) –

答えて

3

標準から関連の引用は、5.2.3 [expr.type.conv]/2

発現Tはのための単純な型指定子または型名指定子であるT()非配列完全オブジェクト型または(おそらくcv修飾された)void型は、指定された型の値を初期化します(8.5; void()の場合は初期化が行われません)。 [注意:Tがcv修飾された非クラス型である場合、cv修飾子は、結果のprvalue(3.10)の型を決定する際に無視されます。末端ノート]

標準で文言が明示的に非クラスタイプのためのconst-volatile修飾がドロップされること(非標準形式で)言及し、しかし、あなたの場合にはタイプがクラスです、注釈は適用されません。 VSは非クラス型に適用されるのと同じ規則を適用しているようです。

+0

説明ありがとう – Frahm

関連する問題