文字列が関数テンプレートの実パラメータとして使用される予期せぬ状況

1414 ワード

場合によっては、cスタイルの異なる文字列を関数テンプレートの同じテンプレートパラメータをインスタンス化すると、実参演繹の過程でしばしば発生する.
思いがけないことに、コンパイルに失敗し、タイプが一致しないと報告されました.
以下の例のように、
#include<iostream>
using namespace std;

/*
*    
*/
template<typename T>
int ref_fun(T & t1,T & t2)
{
	return strlen(t1) - strlen(t2);
}

template<typename T>
int nonref_fun(T t1,T t2)
{
	return strlen(t1) - strlen(t2);
}

int main()
{
	//int a = ref_fun("abcd","abc");
	//Error:              
	//     (const char[5],const char[4])
	int b = nonref_fun("abcd","abc");
	//    

}

このような場合、参照タイプの文字列パラメータコンパイラは、const char[N]のような「文字定数配列」に自動的に変換するので、N値が異なると仮定すると、2つの文字列に対応するタイプが異なるため、同じテンプレートパラメータをインスタンス化することはできない.参照ではなく
タイプの文字列パラメータは、コンパイラが自ら文字配列を文字ポインタタイプに変換するので、異なる長さの文字列は同じ額に変換されます.
文字ポインタタイプなので、同じテンプレートパラメータをインスタンス化できます.
次のコードは、この結論に対する検証コードです.
#include<iostream>
using namespace std;

/*
*    
*/
template<typename T>
void Ref(T & t)
{
	cout<<t<<"ref:"<<typeid(t).name()<<endl;
}

template<typename T>
void nonRef(T t)
{
	cout<<t<<"ref:"<<typeid(t).name()<<endl;
}

int main()
{
	//          
	Ref("abc");
	//           
	nonRef("abc");

	/*
	    :
	abcref:char const [4]
        abcref:char const *
               . . .
        */
}