4

議論の控除が私が予想するように機能しない理由を誰かが教えてもらえますか?私の考え方については、私のコードコメントを参照してください。

#include <iostream>
#include <type_traits>
#include <iomanip>
#include <string>

using namespace std;

template<class T>
void deduce1(T args, string arg){
cout << "template<class T> void deduce1(T args) " << " argument passed in was: " << arg << " deduced as: " << typeid(T).name() << endl;
cout <<  "Is const: " << boolalpha << is_const<T>::value << endl;
cout <<  "Is reference: " << boolalpha << is_reference<T>::value << endl;
cout <<  "Is pointer: " << boolalpha << is_pointer<T>::value << endl;
}

template<class T>
void deduce2(T& args,string arg){
cout << "template<class T> void deduce2(T args) " << " argument passed in was: " << arg << " deduced as: " << typeid(T).name() << endl;
cout <<  "Is const: " << boolalpha << is_const<T>::value << endl;
cout <<  "Is reference: " << boolalpha << is_reference<T>::value << endl;
cout <<  "Is pointer: " << boolalpha << is_pointer<T>::value << endl;
}

template<class T>
void deduce3(T&& args,string arg){
cout << "template<class T> void deduce3(T args) " << " argument passed in was: " << arg << " deduced as: " << typeid(T).name() << endl;
cout <<  "Is const: " << boolalpha << is_const<T>::value << endl;
cout <<  "Is reference: " << boolalpha << is_reference<T>::value << endl;
cout <<  "Is rvalue reference: " << boolalpha << is_rvalue_reference<T>::value << endl;
cout <<  "Is pointer: " << boolalpha << is_pointer<T>::value << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{

int a = 1;
const int b = 5;
int c[] = {12};
int const d[] = {12};
int& e = a;

deduce1(a,"int a = 1");
deduce1(b,"const int b = 5");
deduce1(c,"int c[] = {12}");
deduce1(d,"int const d[] = {12}"); // would have thought is_const<T> would return true any comments?
deduce1(e,"int& e = a");
deduce1(5,"5");

deduce2(a,"int a = 1");
deduce2(b,"const int b = 5"); //would have though type would be deduced as int const comments?
deduce2(c,"int c[] = {12}"); // why is this not returning true as a reference?
deduce2(d,"int const d[] = {12}"); // would have thought is_const<T> would return true any comments
deduce2(e,"int& e = a");

deduce3(a,"int a = 1");
deduce3(b,"const int b = 5");
deduce3(c,"int c[] = {12}"); // why is this not returning true as a reference?
deduce3(d,"int const d[] = {12}"); // would have thought is_const<T> would return true any comments
deduce3(e,"int& e = a");
deduce3(string("Hello"),"string(\"Hello\")"); // why not rvalue reference


return 0;
}
4

1 に答える 1

0

それぞれのコメントに順番に取り組んでいきます。

  1. deduce1d

    template <class T> void deduce1(T args, string arg);
    int const d[] = {12};
    deduce1(d, "int const d[] = {12}"); // would have thought is_const<T> would return true
    

    最初に重要なことは、C++では値によって配列を引数として渡すことができないということです。配列を示す式は、ほとんどすぐに最初の要素へのポインターに減衰します。Tしたがって、ここで推定されるタイプはになりますint const *

    それでも、なぜこれが機能しないのですか?問題は、ポインタがではないことconstです。intポインタが指しているsはですconst。指摘されているタイプのネスを報告したい場合は、ネスをチェックする前にconstを使用する必要があります。したがって、チェックを次のように変更します。remove_pointerconstconst

    cout <<  "Is const: " << boolalpha << is_const<typename remove_pointer<T>::type>::value << endl;
    

    しかし、それが以前に与えていた結果は正解でした。ポインタは確かにそうではありませんでしconstた。実際、ポインタがだったとしても、型の推定が行われる前constにトップレベルconstsが削除されるので、とにかくそうTはなりませconstん。constこの理由は、値を渡す場合、とにかくそれをコピーしているので、引数の本質を本当に気にしないからです。

  2. deduce2b

    template <class T> void deduce2(T& args,string arg);
    const int b = 5;
    deduce2(b,"const int b = 5"); //would have though type would be deduced as int const
    

    ここで何が起こっているのかわかりませんが、私の出力は次のとおりです。

    deduced as: i
    Is const: true
    Is reference: false
    Is pointer: false
    

    まさに期待通り。

  3. deduce2c

    int c[] = {12};
    deduce2(c,"int c[] = {12}"); // why is this not returning true as a reference?
    

    deduce2すべての呼び出しがそう言っているのと同じ理由で、それは参照ではないと言っています(そしてあなたもこの問題を抱えていdeduce3ます)。関数では、のタイプをチェックしていますTが、のタイプはargsですT&。の前の部分のみをチェックしています&。したがって、ここでは、のタイプはargsですが、が参照であるint (&)[1] cかどうかを確認しているだけですint [1]。小切手decltype(args)の代わりにを使用して修正してください。T

  4. deduce2d

    int const d[] = {12};
    deduce2(d,"int const d[] = {12}"); // would have thought is_const<T> would return true
    

    (項目1)deduce1と同じ問題。d

  5. deduce3c

    template <class T> void deduce3(T&& args,string arg);
    int c[] = {12};
    deduce3(c,"int c[] = {12}"); // why is this not returning true as a reference?
    

    (項目3)deduce2と同じ問題。c

  6. deduce3d

    int const d[] = {12};
    deduce3(d,"int const d[] = {12}"); // would have thought is_const<T> would return true
    

    (項目1)deduce1と同じ問題。d

  7. deduce3string("Hello")

    deduce3(string("Hello"),"string(\"Hello\")"); // why not rvalue reference
    

    あなたが「普遍的な参照」について何か知っていると仮定します。スコットマイヤーズは素晴らしい記事を持っており、このテーマについて話します。

    この場合、string("Hello")は右辺値式であるため、型Tは次のように推定されますstring(フォームの推定右辺値参照型の規則によりT&&)。のタイプargsは現在string &&です。decltype(args)したがって、が右辺値であるかどうかを確認すると、trueと表示されます。しかし、Tそれ自体はそうではありません。

T上のすべての型特性がオンになるようにコードを修正するとdecltype(args)、新しい問題が発生します。argsが参照型の場合、期待される特定の型は参照型でconstはありません。constそれは参考になるものがないからです。remove_pointer項目1で使用するのと同様に、を使用remove_referenceして基になるタイプを取得し、それがであるかどうかを確認する必要がありconstます。

于 2012-11-07T10:24:00.847 に答える