3

引数の constness と l(r)valueness を検出する関数を作成しました。

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

何らかの理由で、is_const は const 型 (const int& など) でも常に false を返します。定数をキャプチャするために別のオーバーロードを追加してみました

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

コンパイラは、const int& に適用されると検出があいまいであると不平を言います。したがって、コンパイラは T=const int& を正しく計算していると思いますが、is_const が true を返さないのはなぜですか?

4

1 に答える 1

10

std::is_const<T>トップレベルのみを検出しますconstfoo const、またはのようにfoo* const。orconstのような「内部」は気にしません。foo const*foo const&

const への参照を入力するかどうかを確認したい場合は、最初に参照を取り出す必要があるため、constがトップレベルになります。

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

いずれにせよ、示されている関数は型推論を許可していません。つまりT、 のように明示的に渡す必要がありますdetect<foo const&>(x)。多分あなたは次のようなものが欲しいですか?

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)

于 2012-04-26T18:00:09.890 に答える