STL/CLR を使ってみる
C++/CLI で STL が使えるようなので試してみる。
2011-05-09 関数オブジェクト等を追記
2011-05-09 関数オブジェクト等を追記
準備
とりあえず新規で「 CLR コンソールアプリケーション 」。
stdafx.h には何も定義されていない、無視すればいい。
その前に DLL パスが私の環境 (Visual Studio 2008 professional) で定義されていなかった。
オプションを開いて
$(ProgramFiles)\Reference Assemblies\Microsoft\Framework\v3.5
を「参照ファイル」に追加。
こうしないと Microsoft.VisualC.STLCLR.dll が参照できません。
stdafx.h には何も定義されていない、無視すればいい。
その前に DLL パスが私の環境 (Visual Studio 2008 professional) で定義されていなかった。
オプションを開いて
$(ProgramFiles)\Reference Assemblies\Microsoft\Framework\v3.5
を「参照ファイル」に追加。
こうしないと Microsoft.VisualC.STLCLR.dll が参照できません。
とりあえず vector
MSDN を探しても何故かコンテナ関係しか見つからない。
ということで vector で実験してみる。
ハンドル型( ^ )がちょっとうっとうしいけどほとんど同じに書ける、これはなかなか。
しかしイテレータは ++ 演算子が定義されているはずなんだがエラーになるので next メソッドで。
とにかくマネージド環境でも同じように使えるというのは嬉しいですね。
ということで vector で実験してみる。
#include "stdafx.h" #include <iostream> #include <vector> #include <cliext/vector> #using <mscorlib.dll> //コレはネイティブコードを使う時に必要 using namespace System; #pragma managed //以下はマネージド void ManagedFunc() { cliext::vector<String ^> vec; vec.push_back("あいうえお"); vec.push_back("かきくけこ"); //iterator は IRandomAccessIterator になる cliext::vector<String ^>::iterator ^ it = vec.begin(); cliext::vector<String ^>::iterator ^ itend = vec.end(); int i = 0; for (; it != itend; it->next()) { Console::WriteLine(vec[i++]); //Console::WriteLine(it->get_cref()); //こっちのほうが簡単 } } #pragma unmanaged //以下ネイティブ void UnManagedFunc() { std::vector<std::string> vec; vec.push_back("さしすせそ"); vec.push_back("たちつてと"); std::vector<std::string>::iterator it = vec.begin(); std::vector<std::string>::iterator itend = vec.end(); int i = 0; for (; it != itend; it++) { std::cout << vec[i++].c_str() << std::endl; //std::cout << it->c_str() < std::endl; //解っているならコレで } } #pragma managed //以下はマネージド int main(array<System::String ^> ^args) { ManagedFunc(); UnManagedFunc(); Console::WriteLine("終了するには何かキーを押してください"); Console::ReadKey(); return 0; }
ハンドル型( ^ )がちょっとうっとうしいけどほとんど同じに書ける、これはなかなか。
しかしイテレータは ++ 演算子が定義されているはずなんだがエラーになるので next メソッドで。
とにかくマネージド環境でも同じように使えるというのは嬉しいですね。
普通なテンプレート
とりあえず通常のテンプレートとしては使えるのか?
なるほど問題無いみたい。
template キーワードを generic キーワードに変更するとエラーになる。
generic とは少し違うようだ。
VC++ で T を typename 使うと TCHAR 関連かと少し戸惑ったり...
#include "stdafx.h" using namespace System; namespace me { // typename が正しいけど class と書いても通る template <class T, class T2> T2 calc(T a, T2 b) { return a + b; } } int wmain(int argc, wchar_t* argv[]) { Console::WriteLine("20 + 1.5 = {0}", me::calc(20, 1.5)); //=> 20 + 1.5 = 21.5 return 0; }
なるほど問題無いみたい。
template キーワードを generic キーワードに変更するとエラーになる。
generic とは少し違うようだ。
// error generic <typename T, typename T2> T2 calc(T a, T2 b) { return a + b; }
VC++ で T を typename 使うと TCHAR 関連かと少し戸惑ったり...
関数オブジェクト
関数オブジェクトは使えるのだろうか?
昔作った STL のコードを流用したい場合にはマジで使えそう。
とも感じるけど Generic の List で同じことをやってみる。
関数オブジェクトを用意する必要が無い。
ついでに Python でもやってみる。
#include "stdafx.h" #include <cliext/vector> #include <cliext/algorithm> #include <cliext/functional> using namespace System; using namespace cliext; // 関数オブジェクトテスト // #include <functional> template <class T> ref struct print : public unary_function<T, void> { void operator()(T n) { Console::Write("{0} ", n * 10); } }; ref class Test { public: Test() { vector<int> vec; for (int i=0; i < 10; i++) { vec.push_back(i); } // for_each Test // #include <algorithm> for_each(vec.begin(), vec.end(), gcnew print<int>()); } }; int wmain(int argc, wchar_t* argv[]) { Test^ t = gcnew Test(); //=> 0 10 20 30 40 50 60 70 80 90 return 0; }何も問題無い、ref と gcnew キーワードを使う必要があるだけだ。
昔作った STL のコードを流用したい場合にはマジで使えそう。
とも感じるけど Generic の List で同じことをやってみる。
関数オブジェクトを用意する必要が無い。
#include "stdafx.h" using namespace System; using namespace System::Collections::Generic; ref class Test { public: Test() { List新たに作るならどう考えたって Generic のほうが簡単だよなぁ...list ; for (int i=0; i < 10; i++) { list.Add(i); } for each (int n in list) { Console::Write("{0} ", n * 10); } } }; int wmain(int argc, wchar_t* argv[]) { Test^ t = gcnew Test(); //=> 0 10 20 30 40 50 60 70 80 90 return 0; }
ついでに Python でもやってみる。
#!/usr/bin/env python3 import sys vector = [] for i in range(10): vector.append(i) for n in vector: sys.stdout.write("{0} ".format(n * 10)) #=> 0 10 20 30 40 50 60 70 80 90桁違いに簡単...
Copyright(C) sasakima-nao All rights reserved 2002 --- 2024.