追記:
Ryooooooga様にBoostやC++17以降を使う方法を教えていただきました。詳しくはコメントで
void*を使ってるので実際に使うときは十分注意。
test.h
#pragma once
#include <memory>
#include <functional>
#include <vector>
#include <typeindex>
/**
* void*型に変換された実体のデストラクタを正しく読み出すため構造体
* http://faithandbrave.hateblo.jp/entry/2014/06/04/172754
* から参照
*/
struct void_deleter {
std::function<void(void*)> deleter;
template <typename F>
void_deleter(F f)
{
deleter = f;
}
void operator()(void* p) const noexcept
{
deleter(p);
}
void_deleter() {};
};
/**
* 型の異なるデータを一つに登録するクラス。
*/
class ObjectClass
{
protected:
/**
* 配列.
*/
std::vector< std::pair < std::unique_ptr<void, void_deleter>, char* > >value_;
public:
/**
* コンストラクタ.デストラクタ.
*/
ObjectClass();
~ObjectClass();
/**
* 配列の後ろに追加
* @param val 色々な型データ.
*/
template <typename T>
void push_back(const T &val) {
// 通常のnewと、void_deleter構造体(unique_ptr用)をセットにして追加。
value_.push_back( make_pair( std::unique_ptr<void, void_deleter>(static_cast<void*>(new T(val)), [](void* p) { delete static_cast<T*>(p); }),const_cast<char*>( typeid(T).name() ) ));
};
/**
* 登録したものをargsに参照渡し。
* @param &args 色々な型データ.
* @param int i 要素番号.
*/
template <typename T>
void get(T &args, int i = 0) {
T* pdata = static_cast<T*>(value_[i].first.get());
args = *pdata;
}
/**
* 登録したデータの型名をchar*で返す。
* @param int i 要素番号.
* @return char* 要素名.
*/
char* get_type(int i) {
return value_[i].second;
}
};
使用例
MFC
//日本語を指定
setlocale(LC_ALL, "japanese");
std::unique_ptr<ObjectClass>data(new ObjectClass());
// input
int int_input(1);
char* char_input("hoge");
CString cstring_input("データ");
// 配列に追加
data->push_back(int_input);
data->push_back(char_input);
data->push_back(cstring_input);
// 比較用に別の内容に差し替え
int_input = 11;
char_input = "hogehoge";
cstring_input = "データデータ";
// 出力先
int int_output(-1);
char* char_output("char not found");
CString cstring_output("cstring not found");
// 出力
data->get(int_output);
data->get(char_output, 1);
data->get(cstring_output, 2);
// data->get(cstring_output, 0); //intデータをCStringへ移動しようとするのでエラー
// 表示
cout << "-----input-----" << endl;
cout << int_input << endl;
cout << char_input << endl;
cout << cstring_input << endl;
cout << "--CString--" << endl;
printf("%S\n", cstring_input);
cout << "-----output-----" << endl;
cout << int_output << endl;
cout << char_output << endl;
cout << cstring_output << endl;
cout << "--CString--" << endl;
printf("%S\n", cstring_output);
cout << "-----type-----" << endl;
cout << data->get_type(0) << endl;
cout << data->get_type(1) << endl;
cout << data->get_type(2) << endl;
// キー入力待ち
getchar();