C++のテンプレートの使い方を確かめてみた。
入手先
内容
ソースコードがすべて。
何も言うことはないので、以後、文句をたれてみる。
冗長な記述
コードの見づらさと醜さに拍車がかかった。
関数の実装を記述するたびにtemplate <typename T>
が必要になる。
もともと、関数の実装を記述するたびにclass名が必要だが、さらに<T>
を追加することになる。
おかげさまでC++のテンプレートを利用すると、とてつもなく見づらいコードになる。
Selector.cpp
明示的インスタンス化
なんと、テンプレートを記述しても、使用する型を明示してインスタンス化せねばならない。
template class Selector<int>;
上記のように。
もちろん利用するときは、以下のように普通にclassを宣言する。
Selector<int> s;
なんて面倒なんだ…。同じことを何度書かせれば気が済むんだよ。 まるで役所の公的文書を書いているかのようだ。 うんざり。一度で済ませられないの?
つまりは使う型の数だけ、明示的インスタンス化が必要ということになる。 たとえば以下のように。
template class Selector<int>;
template class Selector<int*>;
template class Selector<char>;
template class Selector<char*>;
template class Selector<double>;
template class Selector<double*>;
template class Selector<SomeClass>;
template class Selector<SomeClass*>;
わあ、関数の実装を書き直さなくても、これ一行で済むんだやったね!
とでも言うと思った?
こういうのを省くためのテンプレートじゃないの?
楽をするためのテンプレートだと思っていたが、中途半端。 もうわざわざ冗長化・煩雑化・難読化するために書いているように思えてきた。
C++はこういう冗長な記述が多すぎる。 書くときも面倒だが、見る気が失せるコードになってしまうのは致命的。
こう書きたいんだよ!
Selector.h
#pragma once
#include <string>
#include <map>
namespace ytyaru.Framework.Container {
class Selector<T>
{
public:
Selector(void);
~Selector(void);
bool Add(string key, T value);
void Select(string key);
T GetSelected();
bool IsContain(string key);
private:
map<string, T> m_map;
T m_selected;
}
}
Selector.cpp
#pragma once
#include "Selector.h"
#include <type_traits>
#include <limits.h>
#include <assert.h>
namespace ytyaru.Framework.Container
{
Selector(void) { m_selected = NULL; }
~Selector(void) {}
bool Add(string key, T value)
{
if (IsContain(key)) { return false; }
else { m_map[key] = value; return true; }
}
bool IsContain(string key)
{
if (0 < m_map.count(key)) { return true; }
else { return false; }
}
void Select(string key)
{
if (IsContain(key)) { m_selected = m_map[key]; }
}
T GetSelected()
{
return m_selected;
}
}
実際のコードとは大違い。
Selector.h
Selector.cpp
所感
私にテンプレートを使いこなす技量はない。