オブジェクトに型の名前とプロパティを関連付けるために、ある種のメタオブジェクトメカニズムをプロジェクトで開発しました(結果:here参照)。私は汚いコードが働いていると私はそれをきれいにしようとしています。以下のダミー構造体を考える:"static virtual"関数を使用したメタオブジェクト
struct A
{
using Self = A;
using Base = void;
static std::string get_type_name(){ return { "A" }; }
static std::vector<int> get_properties(){ return { 0 }; }
};
#define SELF(class_name)\
using Base = Self;\
using Self = class_name;
struct AA : A
{
SELF(AA)
static std::string get_type_name() { return { "AA" }; }
};
struct AAA : AA
{
SELF(AAA)
static std::string get_type_name(){ return { "AAA" }; }
static std::vector<int> get_properties(){ return { 2, 1 }; }
};
私はその階層間でのオブジェクトのタイプ名を取得するには、このコードになってしまった:
// when the type has no Base member:
template<
typename T,
typename std::enable_if<std::is_same<typename T::Base, void>::value>::type* = nullptr
>
typename std::vector<decltype(T::Self::get_type_name())> get_type_names()
{
return { T::Self::get_type_name() };
}
// when the type has a Base member:
template<
typename T,
typename std::enable_if<!std::is_same<typename T::Base, void>::value>::type* = nullptr
>
typename std::vector<decltype(T::Self::get_type_name())> get_type_names()
{
auto data = get_type_names<typename T::Base>();
data.insert(data.begin(), T::Self::get_type_name());
return data;
}
およびプロパティの似たような:
template<
typename T,
typename std::enable_if<std::is_same<typename T::Base, void>::value>::type* = nullptr
>
decltype(T::Self::get_properties()) get_properties()
{
return { T::Self::get_properties() };
}
template<
typename T,
typename std::enable_if<!std::is_same<typename T::Base, void>::value>::type* = nullptr
>
decltype(T::Self::get_properties()) get_properties()
{
auto data = get_properties<typename T::Base>();
auto self_data = T::Self::get_properties();
data.insert(data.begin(), self_data.begin(), self_data.end());
return data;
}
このスニペットでコードをテストする場合:
template<typename T>
void print()
{
std::cout << T::get_type_name() << std::endl << "\thas types:" << std::endl;
for(auto type_name : get_type_names<T>())
{
std::cout << "\t\t" << type_name << std::endl;
}
std::cout << "\thas properties:" << std::endl;
for(auto property : get_properties<T>())
{
std::cout << "\t\t" << property << std::endl;
}
}
int main()
{
print<A>();
print<AA>();
print<AAA>();
return 0;
}
私は、次のような出力が得られます。
A
has types:
A
has properties:
0
AA
has types:
AA
A
has properties:
0
0
AAA
has types:
AAA
AA
A
has properties:
2
1
0
0
この最初のプロトタイプは、名前のためにうまく動作しますが、できるだけ早くオブジェクトはプロパティせずに宣言されているとして、そのベースからのものが複製されます。誰かが問題を解決する簡単な方法を見ていますか?
ボーナスの質問:メタ関数の実装は非常に似ていますが、誰かがコードをどのように分解することができるかのヒントを持っていますか?
A完全なライブの例では、ここでは正しい軌道に乗ってあなたを配置します不完全なソリューションですhere
問題はプロパティで発生しますが、タイプでは発生しません。 – imreal
@imreal問題は型にも発生しますが、私の使用例では常に型が宣言されます。一方、プロパティーはオプションです – wasthishelpful
これは、 'get_type_name'と' get_type_names'の間に違いがありますが、 'get_properties'は同じです。間違ったものが呼び出されるかもしれません。 – imreal