あなたの例にはテンプレートの控除はありません。Derived<int*> d(p);具体的には、テンプレートパラメータをT(int*intへのポインタ)に設定します。派生コンストラクターは、この場合はintへのconstポインターconst Tであるパラメーターを取ります。あなたの混乱は、 intへのconstポインターを宣言せず、代わりにintへのconstポインターではなく、それに変換できないconst intへのポインターを宣言しているためだと思います(前者は、ポイントされた値を変更できますが、後者はしません)。const int* p;
CおよびC++宣言は通常、変数名から外側に向かって読み取られることに注意してください。したがって、const int* pから始めてp、左に移動して表示*し、さらに左に移動して参照してください。constintへのポインタもconst int同様です。これはC宣言の解読に関する優れたガイドであり、cdeclも非常に便利なツールです。p
この例の問題は、 const intへpのポインターですが、のコンストラクターは、であるため、intへのconstポインターを取ります。これは紛らわしいように思えるかもしれませんが、型宣言よりも優先順位が高いと考えることができます。したがって、ではconst intへのポインタを作成する全体に適用され、次に適用されますが、の場合、constはに適用されます。これは実際にはintへのconstポインタになります。Derived<int*>Tint*const*const int *constint*pconst TTint*const T argDargD
これと同じアイデアを使用すると、すべてのFoo例を簡単に解読できます。
Foo(T& a) // a is a reference to a value of type T
Foo(T a) // a is a value of type T
Foo(T* a) // a is a pointer to a value of type T
Foo(const T a) // a is a constant value of type T
Foo(const T* a) // a is a pointer to a constant value of type T
Foo(const T& a) // a is a reference to a constant value of type T
一般Foo(T a)にFoo(const T a)、引数が定数変数にコピーされるかどうかは呼び出し元にとって重要ではないため、オーバーロードすることはできません。
より具体的には、if Tis char *(charへのポインタ)
Foo(char *&a) // a is a reference to a pointer to a char
Foo(char *a) // a is a pointer to a char (*)
Foo(char **a) // a is a pointer to a pointer to a char
Foo(char *const a) // a is a constant pointer to a char (cannot overload with (*))
Foo(char *const *a) // a is a pointer to a constant pointer to a char
Foo(char *const &a) // a is a reference to a constant pointer to a char
もしそうならT(const char*const charへのポインタ)物事はほとんど同じです
Foo(const char *&a) // a is a reference to a pointer to a const char
Foo(const char *a) // a is a pointer to a const char (*)
Foo(const char **a) // a is a pointer to a pointer to a const char
Foo(const char *const a) // a is a constant pointer to a const char (cannot overload with (*))
Foo(const char *const *a) // a is a pointer to a constant pointer to a const char
Foo(char *const &a) // a is a reference to a constant pointer to a const char
Tis char* const(文字へのconstポインタ)の場合、がすでにconstである場合と同等であるため、すべてのオーバーロードは冗長const Tです。const TTT
Foo(char *const &a) // a is a reference to a const pointer to a char (+)
Foo(char *const a) // a is a const pointer to a char (*)
Foo(char *const *a) // a is a pointer to a const pointer to a char (^)
Foo(char *const a) // a is a const pointer to a char (same as (*))
Foo(char *const *a) // a is a pointer to a const pointer to a char (same as (^))
Foo(char *const &a) // a is a reference to a const pointer to a char (same as (+))