2016-12-28 3 views
1

テンプレート関数で型Tの親を取得し、私は以下のクラスをしたと仮定型Tの親を見つけ、関数base_ofを実装しますか?私はテンプレート関数の型クラスTの親が何であるかを知りたい

編集:私は私のためのオブジェクトを作成するファクトリクラスまし

:registerType機能で

template <typename B> 
class Factory{ 
public: 
    template <typename D> 
    void registerType(std::string name) 
    { 
     static_assert(std::is_base_of<B, D>::value, "class doesn't derive from the base"); 
     table_[name] = &createFunc<D>; 
    } 
    B* create(std::string name) 
    { 
     const auto it = table_.find(name); 
     if(it != table_.end()) 
      return it->second(); 
     FILE_LOG(logERROR) << "unidentified option, acceptable options are:"; 
     for(auto const &m : list()) 
      FILE_LOG(logERROR) << '\t' << m; 
     return nullptr; 
    } 

    std::vector<std::string> list() 
    { 
     std::vector<std::string> lst; 
     for(auto const &iter : table_) 
      lst.push_back(iter.first); 
     return lst; 
    } 
private: 
    template<typename D> 
    static B* createFunc() 
    { 
     return new D(); 
    } 
    typedef B* (*PCreateFunc)(); 
    std::map<std::string, PCreateFunc> table_; 
}; 

を私はタイプDのいくつかのプロパティを設定したい確かに私が何をしたい ですまたは親であり、次にcreate関数では、それに基づいてオブジェクトを作成したいと思います。

+0

を扱っていませんか?私のためにXY問題のように聞こえる。 –

+2

多重継承ではどうしたらいいですか? – Quentin

+0

私は、ファクトリクラス(抽象ファクトリデザインパターンに基づいています)を作成すると、オブジェクトがそのプロパティまたはその親をチェックし、次にそれ(プロパティの値)によってオブジェクトが作成されます。私はそのタイプが何で、そのタイプが何であるかを知りたいです。 – abdolahS

答えて

0

定義する必要のない関数宣言をいくつか使用できます。それは、このような場合には、あなたが正確なinvokationsの間に一致している、という事実を利用

#include<utility> 
#include<typeinfo> 
#include<iostream> 

class A{}; 
class B: public A{}; 
class C: public B{}; 

B base_of(const C &); 
A base_of(const B &); 

template<typename T> 
void getBaseHashCode() { 
    std::cout << typeid(decltype(base_of(std::declval<T>()))).name() << std::endl; 
} 

int main() { 
    getBaseHashCode<B>(); 
    getBaseHashCode<C>(); 
} 


最小限、実施例に従います。それは非常に弱い解決策ですが、質問のサンプルコードで動作します。


つまり、質問全体がXY問題のように見えるということに私は同意しました。コメントで@ Jarod42で述べたように

EDIT

、より多くの慣用的な(そして冗長)の方法は、特性を使用することによりだろう。これはまた、多重継承に起因する問題を解決します

#include<typeinfo> 
#include<iostream> 

class A{}; 
class B: public A{}; 
class C: public B{}; 

template<typename> struct base_of; 
template<> struct base_of<B> { using type = A; }; 
template<> struct base_of<C> { using type = B; }; 

template<typename T> 
void getBaseHashCode() { 
    std::cout << typeid(typename base_of<T>::type).name() << std::endl; 
} 

int main() { 
    getBaseHashCode<B>(); 
    getBaseHashCode<C>(); 
} 


最小限、実施例に従います。 base_ofスペシャライゼーションのデザイナーは、基本クラスの1つをのロールに昇格させることになります。

+0

ありがとうございますが、それは多くのモジュールとクラスを持つプロジェクトのための良いデザインではないようです! – abdolahS

+1

@abdolahSそれがコードの後の私のコメントの理由です。 – skypjack

+1

カスタムの特性を作成する方がより慣れているようです: 'template <> struct base_of {use type = B;};'もっと冗長であっても... – Jarod42

0

またtypedef INGを自動化するために、いくつかの親ラッパーを使用して検討するかもしれない:

#include <type_traits> 
#include <typeinfo> 
#include <iostream> 

template <class P> 
struct base: P { 
    using base_type = P; 
}; 

struct A{ }; 
struct B: base<A>{ }; 
struct C: base<B>{ }; 

template <class T> 
auto base_of(T) -> typename T::base_type; 

template <class T> 
using base_of_t = decltype(base_of(std::declval<T>())); 

int main() { 
    std::cout << typeid(base_of_t<C>).name() << std::endl; 
} 

は出力:

1B

c++filt -t 1Bの出力:

B

[live demo]

あなたがそれを必要な理由、それはまだ多重継承

関連する問題