チュートリアル的な記述4
ファイル操作
#include <iostream> #include <fstream> void fileSample() { // file std::ofstream ofs("test.txt"); if (!ofs) { std::cerr << "[error]open file" << std::endl; std::exit(1); } ofs << "Hello, World\n123" << std::endl; // auto close std::ifstream ifs("test.txt"); if (!ifs) { std::cerr << "[error]open file for ifstream." << std::endl; std::exit(1); } std::string bufstr; ifs >> bufstr; std::cout << bufstr << std::endl; //[note] output is Hello, std::ifstream ifs2("test.txt"); if (!ifs2) { std::cerr << "[error]open file for ifstream." << std::endl; std::exit(1); } std::string bufstr2; getline(ifs2, bufstr2); std::cout << bufstr2 << std::endl; //[note] output is Hello, World getline(ifs2, bufstr2); std::cout << bufstr2 << std::endl; //[note] output is 123 if (ifs2.eof()) { std::cout << "eof" << std::endl; //[note] output is 123 } }
チュートリアル的な記述3
変数
#include <sstream> #include <iomanip> #include <fstream> void basicVariable() { const int c = 10; // ref int r = 0; int& r2 = r; r2 = 100; std::cout << r << std::endl; // 100 // 構造体 Point p; p.x = 10; p.y = 10; std::cout << p.d2() <<std::endl; // enum // enum ColorType1 type1 = ColorType1::RED; ColorType2 type2 = ColorType2::RED; ColorType3 type3 = ColorType3::RED; ColorType1 type4 = RED; // ColorType2 type5 = RED; できない // ColorType3 type6 = RED; できない std::cout << type1 << std::endl; std::cout << static_cast<int>(type2) << std::endl; std::cout << static_cast<int>(type3) << std::endl; std::cout << type4 << std::endl; // auto 型推論 auto x = "x"; // 文字列 std::string z = "ac"; auto y = 3.0; auto z1 = z + z; auto z2 = x + z; auto z3 = z + x; std::string z5 = z.append(x); // acx std::string z6 = z.append(z); // acxacx z.empty();// empty check //auto z4 = x + x; //できない。 const char* std::cout << x << std::endl; std::cout << y << std::endl; std::cout << z << std::endl; // acxacx std::cout << z5 << std::endl;// acx std::cout << z6 << std::endl;// acxacx // decltype int sample = 100; decltype(sample) sample2 = 200; // Type of sample2 is Int. decltype(getValue()) sample3 = 3.3;// Type of sample3 is Int. std::cout << sample << sample2 << sample3 << std::endl; // escape std::string stresc = "a\nb\nc"; std::string stresc2 = R"(a b c)"; std::cout << stresc << std::endl; std::cout << stresc2 << std::endl; // null pointer int* a = nullptr; if (a == nullptr) { std::cout << "nullptr" << std::endl; } }
文字列
#include <iostream> void stringUse() { std::string x = "aaa"; std::string y = "bbb"; std::string z = x + y; std::cout << z << std::endl; }
ベクトル
#include <iostream> #include <vector> void vectorUse() { std::vector<int> v = {1,5,10,100}; v[2] = 100; v.push_back(50); /// もっと簡単に表示してしたい for (int x: v) { std::cout << x << std::endl; } std::vector<int> v2 = {1,3,2,5}; /// +は使えないのだろうか。 C++にカテゴリ拡張はない。 v2.insert(v2.end(), v.begin(), v.end()); /// coutが面倒だ。。 std::cout << "v2" << std::endl; for (int x: v2) { std::cout << x << std::endl; } }
チュートリアル的な記述2
参照
// class class CPYCost { public: CPYCost(); ~CPYCost(); /// オブジェクトのコピー用の代入演算子 CPYCost& operator=(const CPYCost& rhs); int x; private: };
void refAdd(int &x); void pAdd(int *x); void refUse() { // 参照 int x = 1; int& r = x;// xの参照を取得 r = 2; // xは2になる。 // 参照はNULLを代入できない。 // ポインタ int z = 1; int* p = &z; *p = 2; // zは2になる。 int t = 10; refAdd(t); // tが11になる。 pAdd(&t); // tが12になる。 CPYCost *c = new CPYCost(); c->x = 1000; CPYCost d; d.x = 2500; CPYCost &dd = d; CPYCost ddd = d; std::cout << ddd.x << std::endl; } void refAdd(int &x) { x++; } void pAdd(int *x) { (*x)++; }
ラムダ式
void lambdaUse() { auto l = [](int x)->int { return x+3; }; int x = l(5); // NG // auto l2 = [](int a)->int { // return x+10; // }; // xをキャプチャ auto l2 = [x](int a)->int { return x+10; }; // すべてキャプチャ auto l4 = [=](int a)->int { return x+10; }; std::cout << x << std::endl; }
チュートリアル的な記述
関数
int twice(int x); int twice(int x) { return x * 2; }
auto nfunc2(int x) -> decltype(x) { return x * 100; }
namespace FunctionauUse { int add(int x); void echo(int x); } /// 関数を変数に格納する。 void functionalUse() { std::function<void(int)> f = FunctionauUse::echo; std::function<void(int)> f2 = FunctionauUse::add; f(3); f2(5); } void FunctionauUse::echo(int x) { } int FunctionauUse::add(int x) { return x+1; }
テンプレート
template <typename R, typename T1, typename T2> R echo(T1 x, T2 y) { return static_cast<R>(x+y); }
構造体
struct Point { int x; int y; int d2(); // メソッド生やせる。 }; int Point::d2() { return this->x + this->y; }
クラス
// class class Man { public: void hello(); Man(); // default constructer Man(std::string name); ~Man(); // static int commonNumber; bool operator==(const Man& rhs) const; inline bool operator!=(const Man& rhs) const { return !(*this == rhs); } private: std::string name; int age; void util(); int n = 10; }; void Man::hello() { std::cout << "Hello, my name is " << this->name << std::endl; } void Man::util() { std::cout << "util" << std::endl; } Man::Man() : name("name"), age(0){ // commonNumber++; } Man::Man(std::string name) { this->name = name; age = 0; // commonNumber++; } Man::~Man() { std::cout << "dec" << std::endl; } void hello(Man *m) { m->hello(); } bool Man::operator==(const Man &rhs) const { return name == rhs.name; } void classUse() { /// クラス Man *man = new Man(); man->hello(); delete man; }
テンプレート使用
template <typename T> class Poi { public: void echo(T x); }; template <typename T> void Poi<T>::echo(T x) { std::cout << "echo" << x << std::endl; }
enum
enum ColorType1 : int { GREEN,RED,YELLOW }; enum struct ColorType2 : int { GREEN,RED,YELLOW }; /// enum structとenum class は同じ enum class ColorType3 : int { GREEN,RED,YELLOW };
namespace
namespace spaceA { double getValue(); namespace specialB { double getValue(); } inline namespace Util { double getUtilValue(); } } namespace { const int myMAX2 = 100; } namespace spaceMAX { const int myMAX = 1000; } void nameSpaceUse() { /// 名前空間 auto v = getValue(); auto v2 = spaceA::getValue(); auto v3 = spaceA::specialB::getValue(); auto v4 = spaceA::getUtilValue(); using namespace spaceA; auto v5 = getUtilValue(); /// alias namespace B = spaceA::specialB; auto b = B::getValue(); std::cout << v << std::endl; std::cout << v2 << std::endl; std::cout << v3 << std::endl; std::cout << v4 << std::endl; auto max = spaceMAX::myMAX; auto max2 = myMAX2; std::cout << max << max2 << std::endl; } double getValue() { return 2.0; } namespace spaceA { double getValue() { return 20.0; } namespace specialB { double getValue() { return 30; } } inline namespace Util { double getUtilValue() { return 50; } } }
window.location.hrefがきかない
バグがある。
How to fix window.location issue in iOS9 UIWebview - Stack Overflow
setTimeOutで次のイベントループまでまって実行してやる必要がある。
開発用サーバ
WebPackの開発用サーバを使う。
webpack-dev-serverをnpmでインストール。
webpack.config.jsに
devServer: { contentBase: path.resolve(__dirname, 'app'), port: 3000 }
を等と設定、また、outputのpublicPathも追加してcontentBaseに合わせておく(そうしないとpath:を起点にjs等が参照されてしまう。)。
output: { path: path.resolve(__dirname, 'app/dist'), publicPath: "app/" },
npmにコマンドを登録し
"scripts": { "server": "webpack-dev-server --inline", }
npm run server等とやればlocalhost:3000でアクセスできる。
履歴をしらべてコピーする。
履歴を調べて古かったらコピーするというスクリプトを書いてみた。 makefileの代わりに
import sys import os import shutil import re # pathlistで指定したフォルダのファイルに対応するファイルがbasepath以下にある場合、basepathの方が古くなっていたらコピーする。 basepath = "./tmp/" pathlist = ["./dist","./html","./lib"] def fileList(path): list = [] for root,dirs,files in os.walk(path): t = [os.path.join(root,f) for f in files] list.extend(t) return list def isLeftPathIsNew(path1, path2): if not os.path.exists(path1): return False if not os.path.exists(path2): return False time1 = os.stat(path1).st_mtime time2 = os.stat(path2).st_mtime # print(path1 + str(time1) + ">=" + path2 + str(time2)) if time1 >= time2: return True return False for path in pathlist: # print("\n") fList = fileList(path) for f in fList: reg = r'\..*' if re.match(reg, os.path.basename(f)): # print("Skip" + f) continue tf = basepath + f[2:] if isLeftPathIsNew(tf,f): # print("new!"+tf) continue else: print("old!"+tf) dir = os.path.dirname(tf) if not os.path.exists(dir): print("makedir", dir) os.makedirs(dir) shutil.copy(f,tf)
plugin
webpack plugin
webpack pluginは
apply(compiler) {}
を持つクラスとして定義して、 webpack.config.jsにおいて
plugins: [ new HelloPlugin() ]
のように入れてやれば良い。
const pluginName = 'HelloPlugin'; class HelloPlugin { apply(compiler) { compiler.hooks.run.tap(pluginName, compilation => { console.log("Hello"); }); } }
hookの内容は
初歩
javaプラグインの使用
build.gradle
apply plugin: 'java'
プロジェクトとタスク
プロジェクトは複数のタスクから構成される。
タスク
分割不可能な作業単位
build.gradle
task hello << { println 'Hello world!' }
実行は
gradle -q hello
-qはログの抑制
タスクの依存
task hello << { println 'Hello world!' } task intro(dependsOn: hello) << { println "I'm Gradle" }
あとから依存関係を追加
task hello << { println 'Hello world!' } task intro << { println "I'm Gradle" } hello.dependsOn intro
タスクにアクションの追加
task hello << { println 'Hello world!' } hello.doFirst { println "I'm Gradle" }
doLast(これは<<と同じ)等
拡張タスクプロパティ
task hoge { ext.foo = "4" } task poi << { println hoge.foo }
メソッドの使用
task hoge { ext.foo = "4" }
デフォルトタスク
defaultTasks 'clean', 'run'
コピー
task copy_jsapp(dependsOn: build) { println("copy jsapp/app") file("hoge").mkdir() file("hoge/poge.txt").text = "a" file("dist").mkdir() file("dist/tmp.txt").text = "b" copy { from 'hoge' into 'dist' } }
スクロールを一時禁止
このような感じで
onKeypadOpen:() => { $(document).on("touchmove.noScroll", function(e:JQuery.Event) { e.preventDefault(); }) }, onKeypadClose:() => { $(document).off("touchmove.noScroll"); },