VisualStudio2012で確認。
検索してみると次のページがヒットしました。
- http://vene.wankuma.com/ecma372/09_lexicals.aspx
- http://vene.wankuma.com/ecma372/15_expression.aspx
- http://vene.wankuma.com/ecma372/31_generics.aspx
これらのページを参考に、以下のサンプルコードを書いて確認してみました。出力を行うメソッドの出力内容は、右にコメントで記述しています。
#include<stdio.h> #include<typeinfo> #include<msclr/marshal.h> using namespace System; void OverloadedFunc(const char*){ puts("const char *を受け取りました"); } void OverloadedFunc(char*){ puts("char *を受け取りました"); } void OverloadedFunc (String^){ Console::WriteLine("Sytem::String ^を受け取りました"); } template<typename T> void TemplateFunc(T){ puts(typeid(T).name()); } generic<typename T> void GenricFunc(T){ Console::WriteLine(T::typeid); } int main(){ String ^s1 = "abc"; // 文字列リテラルからは暗黙にString^に変換可能 String ^s2 = L"あいう"; // ワイド文字列リテラルからも暗黙に変換可能 Uri ^uri = gcnew Uri("http://www.google.co.jp"); // String^を引数とするものも呼び出せる Object ^obj = "abc"; // String^に暗黙に変換され、Object^にアップキャストされる Console::WriteLine(obj::typeid); // "System.String" char *cStr = "abc"; // C++のポインタ型経由 // String ^errorStr = cStr; // charポインタ及びchar配列からはconstであったとしても、String^の暗黙的な変換はない String ^s3 = gcnew String(cStr); // Stringのコンストラクタを通すと変換可能 String ^s4 = ::msclr::interop::marshal_as<String^>(cStr); // marshalを使っても変換可能 puts(typeid("abc").name()); // "char const [4]" puts(typeid("abc"-0).name()); // "char const [4]" // puts(typeid("abc"+0).name()); // コンパイルエラー auto s = ("abc"+0); // 一時変数を媒介せずにtypeidを使う方法がわかりませんでした Console::WriteLine(s::typeid); // "System.String" Console::WriteLine("abc"+0); // "abc0"; // Console::WriteLine("abc"->Length); // ->入力後インテリセンスが働くのに、コンパイルエラーとなる OverloadedFunc("abc"); // "Sytem::String^を受け取りました" OverloadedFunc(L"あいう"); // "Sytem::String^を受け取りました" TemplateFunc("abc"); // "char const *" GenricFunc("abc"); // "System.String" return 0; }
加法演算子+を文字列リテラルに対して適応した場合、注意が必要となりそうです。
しかしまあ、インテリセンスの候補として表示されるものがコンパイルエラーとなるのは混乱の元になりかねないような・・・。
上記コードのs::typeid行にて「'::typeid' が後に続く名前は型名である必要があります」と言ってきましたが実行可能ですし・・・。