2012-04-26 10 views
3

引数のconstとl(r)の高さを検出する関数を作成しました。いつもの例のconst int型&ため、constのタイプにも、falseを返しますis_const何らかの理由でC++ 11:完璧な転送でのconst

template<class T> std::string 
detect(typename std::remove_reference<T>::type&&) { 
    return std::string(std::is_const<T>::value ? "const " : "") + "rvalue"; 
} 
template<class T> std::string 
detect(typename std::remove_reference<T>::type&) { 
    return std::string(std::is_const<T>::value ? "const " : "") + "lvalue"; 
} 

、。私はconst性

template<class T> std::string 
detect(const typename std::remove_reference<T>::type&) { return "const lvalue"; } 

コンパイラは、その後のconst int型&に適用した場合に曖昧であることが検出文句キャプチャするために、別のオーバーロードを追加しようとしました。だから、私はコンパイラがT = const int &を正しいと理解していると思うが、なぜis_constはtrueを返さないのだろうか?

+1

どのように 'detect'を呼びますか?パラメータの 'T 'は推論されていないコンテキストにあるため、明示的に指定する必要があります。 '(何か)を検出する'。どのような目的を破るか。 –

+0

は、転送機能によって検出されます。 –

答えて

9

std::is_const<T>は、最上位constのみを検出します。 foo const、またはfoo* constと同様です。それはfoo const*またはfoo const&のような "内部" constを気にしません。

何が欲しいのタイプのconstへの参照は、あなたが最初の参照を取る必要があるかどうかを確認することですので、constがトップレベルになった場合:いずれの場合で

std::is_const<typename std::remove_reference<T>::type>::value 

、機能がdoを示しますタイプ控除を許可していません。つまり、detect<foo const&>(x)のように、Tを明示的に渡す必要があります。たぶんあなたは次のようなものが欲しいですか?

template<class T> std::string 
detect(T&&) { // have T be deduced 
    return std::string(std::is_const<typename std::remove_reference<T>::type>::value ? "const " : "") 
     + (std::is_lvalue_reference<T>::value? "lvalue" : "rvalue"); 
} 

detect(x)のように呼び出すことができます。

関連する問題