ぷろみん

プログラミング的な内容を扱ってます

Visual Studio Community 2015のデフォルトテーマ変更

VS Community 2015をインストールしたら、また白くなっていたので黒に戻そうとしましたが、どこから設定するか調べるのに思ったより手こずったのでメモしときます。

Tools -> Options -> Environment -> General -> Color Theme

一番上にあるのに気付かなかった!

Fonts and Colorsとかに気をとられてしまっていました。

静的optional

モチベーション

ヘッダの依存性を減らしたい(コンパイラファイアウォールを強くしたい)
しかし、動的メモリ確保を行いたくない

おしいoptional

optionalは静的確保できるポインタの様な物です。
静的型をnullableにする為に使われます。

後でコンストラクトできるという特性から不完全型で構築できるかなと期待しますが、できません。
なぜなら静的なメモリを最初に用意する必要がある為です。
つまり、型のサイズさえ分かれば不完全型での宣言が可能になります。

実装

// optional.h
#pragma once
#include <cstring>

namespace torini{

// optionalの簡易イメージ
template<class T, int N>
class Optional{
public:
    void Construct(){
        T t;
        std::memcpy(this, &t, N);
    }
    
    T* operator ->(){
        return reinterpret_cast<T*>(this);
    }
private:
    // 通常はこれに加えて構築済みかどうかのフラグが存在する
    char storage[N];
};

}
// foo.h
#pragma once
#include <string>

namespace torini{

// 前方宣言用。なんでも良い
class Foo{
public:
    void Print() const;

private:
    std::string message_ = "hello world";
};

}
// foo.cpp
#include "foo.h"
#include <iostream>

namespace torini{

void Foo::Print() const{
        std::cout << message_ << std::endl;
}

}
// foo_size.h
#pragma once

namespace torini{

int GetFooSize();

}
// foo_size.cpp
#include "foo_size.h"
#include "foo.h"

namespace torini{

int GetFooSize(){
    // Fooのサイズを知る為にはfoo.hが必要
    return sizeof(Foo);
}

}
// main.cpp
#include "optional.h"
#include "foo_size.h"

namespace torini{

// torini::Fooを前方宣言だけする
class Foo;

}

int main(){
    // 前方宣言とサイズを取得する事により静的ストレージを確保しつつ好きなタイミングでコンストラクトできる
    torini::Optional<torini::Foo, torini::GetFooSize()> foo;

    // foo.hをincludeしないとコンストラクトはできない
    //foo.Construct();
    //foo->Print();
}

感想

面倒なので計測して問題時間が支配的になるまでは適当で良いと思います。

サイズ取得の為の関数がジェネリックじゃないのも良くないですし。

Caps LockキーをCtrlに置換する

Windowsでの話です。
ソフト入れたり大げさな事せずにできないかと調べたら丁度良い物がありました。

www.edandersen.com

Windowsキー+Rで出現する「ファイル名を指定して実行」でpowershellと打ち込んでOKをクリック

立ち上がった青い画面のウィンドウに以下をコピペしてEnter。

Start-Process powershell -verb runAs

管理者権限を確認するポップアップが出現するので許可します。
すると新しく青い画面が出現するので、新しい方へ以下をコピペしてEnter。

Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\Keyboard Layout" -name "Scancode Map" -Value ([byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x1d,0x00,0x3a,0x00,0x00,0x00,0x00,0x00))

後は再起動したらCaps Lockキーの煩わしさから解放されているはずです。

複数のキーを置換する

ついでにInsertをDeleteに置き換えを追加したい場合は

0x02, 0x00, 0x00, 0x00 // エントリ数(Caps Lock -> Ctrlと終了の2つ)

0x03, 0x00, 0x00, 0x00 // Caps Lock -> CtrlとInsert -> Deleteと終了の3つ

に変更し

0x53, 0xE0, 0x52, 0xE0 // Insert -> Delete

を追加した以下のスクリプトを実行します。

Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\Keyboard Layout" -name "Scancode Map" -Value ([byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x53,0xE0,0x52,0xE0,0x1d,0x00,0x3a,0x00,0x00,0x00,0x00,0x00))

参考

「Caps」と「Ctrl」の入れ替え

修正:C++のAbstractFactoryはvirtualを使わない

C++のAbstractFactoryはvirtualを使わない - ぷろみん

前回のが抽象化できてない事が発覚したので修正しました。
前回のに修正を乗っけようと思ったのですが、そうするとMixinらへんも関係無くなるので新しいのにしておきました。

抽象化

#include<iostream>
namespace torini {

    class Toy {
    public:
        void Play() const {}
    };
    
    class Game {
    public:
        void Play() const {}
    };
    
    // CRTP
    template<class Factory>
    class AbstractFactory {
    public:
        auto CreateToy() {
            return static_cast<const Factory&>(*this).template Create<Toy>();
        }
        
        auto CreateGame() {
            return static_cast<const Factory&>(*this).template Create<Game>();
        }
    };
    
    class FactoryA : public AbstractFactory<FactoryA> {
    public:
        template<class Product>
        Product Create() const {
            std::cout << "FactoryA" << std::endl;
            return Product();
        }
    };
    
    class FactoryB : public AbstractFactory<FactoryB> {
    public:
        template<class Product>
        Product Create() const {
            std::cout << "FactoryB" << std::endl;
            return Product();
        }
    };
}

int main() {
    auto factory = torini::FactoryB();
    
    auto toy = factory.CreateToy();
    toy.Play();

    auto game = factory.CreateGame();
    game.Play();
}

C++のAbstractFactoryはvirtualを使わない

抽象化ができてなかったので修正しました。

修正:C++のAbstractFactoryはvirtualを使わない - ぷろみん

継承

C++では出来る限り継承は使わない方が良いです。
理由としては結びつきが強すぎるからです。
メンバに持って目的の挙動を達成できるのなら、そちらの方が優れています。

Mixin

出来る限り使わない、ではどんな時なら使って良いのか。その使って良い時がMixinとして利用する場合です。
特定のオブジェクトに特定の性質を加える場合、幅広い選択肢があり、再利用性に優れます。また、役割が明確化します。

AbstractFactory

namespace torini {

    class Toy {
    public:
        void Play() const {}
    };
    
    class Game {
    public:
        void Play() const {}
    };

    template<class Product>
    class AbstractFactory {
    public:
        Product Create() const {
            return Product();
        }
    };
    
    template<class ...Types>
    class Factory : public AbstractFactory<Types>... {};

}

int main() {
    auto factory = torini::Factory<torini::Toy, torini::Game>();
    
    auto toy = factory.torini::AbstractFactory<torini::Toy>::Create();
    toy.Play();
    
    auto game = factory.torini::AbstractFactory<torini::Game>::Create();
    game.Play();
}

factory.torini::AbstractFactory<torini::Toy>::Create();が辛い感じなのでfactory.Create<torini::Toy>()と書けてかつfactoryで定義したCreateのみ使えるような方法が分かる方がいたら是非とも教えてくださいな。

ポインタよりも参照を使おう

あんまり関係の無い所

int& aint &aのどちらで書くでしょうか?
私はint &aの方で書きます。

    // int i;
    // int *ip;
    // int *const ipc = &i;
    // int &ir = i;
    int i, *ip, *const ipc = &i, &ir = i;
    // const int ci = 0;
    // const int *cip;
    // const int *const cipc = nullptr;
    // const int &cir = i;
    const int ci = 0, *cip, *const cipc = nullptr, &cir = i;
    // int constでも良い

上記の様に最初のint&の関連性が低い為です。

    int a = 0;

    // 間違えそう!
    // int &b = a;
    // int c = a;
    int& b = a, c = a;

特性に注目する

int main(){
    int i, *ip, *const ipc = &i, &ir = i;
    const int ci = 0, *cip, *const cipc = nullptr, &cir = i;
    
    // mutable
    i = 0;
    ip = &i;
    cip = &i;
    
    // writeable
    *ip = 0;
    *ipc = 0;
    ir = 0;
}

mutableな変数は自身の値を再代入できます。
writeableな変数は他の変数の値を書き換える事ができます。

ここで紛らわしいのがiciです。
imutableなばかりに先頭にconstを付けた場合、変数の変更ができないように考えてしまいます。

先頭にconstを付ける事によってwriteableでは無くなり、*constを付ける事によってmutableでは無くなると考えると分かりやすいです。

参照は分かりやすい

この特性で参照を考えると参照は非常に分かりやすいです。
参照はmutableではありません。
int &irwriteableです。
const int &cirwriteableではありません。

分かりやすい!

push_backよりもemplace_backを使おう

emplace

push_backでは無駄なコストが発生してしまいます。
そこで、直接コンストラクトできるemplace_backがC++11から追加されました。

#include<vector>

namespace torini{

struct Data{
    Data(int, int, int){}
};

}

int main(){
    std::vector<torini::Data> v;
    // 無駄にコンストラクトしてしまう
    v.push_back(torini::Data(0, 1, 2));

    // 綺麗だし、コンストラクトコストが発生しない
    v.emplace_back(0, 1, 2);
}

使い分け

全部emplace_backでも良い気はしますが、あえて明示的にする為にコンストラクタが存在する要素の場合のみemplace_backを使う等が良い気がします。