これらの定義を考えてみましょう:
/*** full type information with typeid ***/
template <class> class Type{};
template <class T> std::string typeStr()
{ return typeid(Type<T>).name(); }
/*** function template for parameter deduction ***/
template <class T> void func(const T &a)
{
std::cout << "Deduced type for T is: " << typeStr<T>() << std::endl;
std::cout << "\targument type is: " << typeStr<decltype(a)>() << std::endl;
}
constへのポインタ付き
次のステートメントが実行された場合:
const int i=5, *ip=&i;
func(ip);
出力は次のとおりです。
Deduced type for T is: 4TypeI**PKi**E
したがってT
、実際には定数整数へのポインターとして推定されます。引数が const への参照であるという事実は、推論を変更しません。これは、ポインターの constness が低レベルであるため、予想されることです。
しかし、constの配列で
それにもかかわらず、次のステートメントが実行された場合:
const int ia[3] = {3, 2, 1};
func(ia);
出力は次のとおりです。
Deduced type for T is: 4TypeI**A3_i**E
したがって、実際には 3 つの非const 整数T
の配列として推定されます。引数が const への参照であるという事実は、配列要素に滑り込んでいるかのように、推定を変更します。const
実際、CL の 18 までのバージョンはT
、3 つの const 整数の配列が標準であると予想していたので推測していましたが、v19 以降、GCC と Clang が行っていること (つまり、非const として推測) に収束したようです。
したがって、後者の動作が標準であると想定していますが、その根拠は何でしたか? ポインタのように振る舞わないのは驚くべきことかもしれません。
編集:ディップコメントに続いて、この動作に関連するCWGの問題へのポインタ、彼が実際にこの回答にコメントとして投稿したポインタをここに報告します(実際にこの新しい質問を提起した回答... C ++は深いトンネルのように感じます)