あなたの例にはテンプレートの控除はありません。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*>
T
int*
const
*
const int *
const
int
*
p
const T
T
int*
const T argD
argD
これと同じアイデアを使用すると、すべての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 T
is 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
T
is char* const
(文字へのconstポインタ)の場合、がすでにconstである場合と同等であるため、すべてのオーバーロードは冗長const T
です。const T
T
T
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 (+))