[英]Generate a unique type or id for each template instantiation? ( example observer pattern )
Is there a way or technique to generate unique types or ids for each template instantiation at compile time? 是否有一种方法或技术可以在编译时为每个模板实例化生成唯一类型或ID?
For example this observer pattern: 例如,这个观察者模式:
#include <set>
#include <iostream>
template <typename T>
struct type2type {}; // maybe int2type
template<class T, class T_UNIQUE>
struct OBSERVER_BASE
{
virtual void notify ( T, type2type< T_UNIQUE > ) = 0;
};
template<class T, class T_UNIQUE>
struct SUBJECT_BASE
{
// This i like to do without the T_UNIQUE parameter
typedef T_UNIQUE unique_type;
std::set< OBSERVER_BASE< T, unique_type >* > my_observer{};
void do_notify ()
{
for ( auto obs : my_observer )
obs->notify ( T{}, type2type< unique_type >{} );
}
};
class X {};
class Y {};
// manual unique required?
class Subject_A : public SUBJECT_BASE< X, Subject_A > {};
class Subject_B : public SUBJECT_BASE< X, Subject_B > {};
class Subject_C : public SUBJECT_BASE< Y, Subject_C > {};
// typedef UNIQUE_. only to illustrate the idea
typedef typename Subject_A::unique_type UNIQUE_A;
typedef typename Subject_B::unique_type UNIQUE_B;
typedef typename Subject_C::unique_type UNIQUE_C;
class Observer :
public OBSERVER_BASE< X, UNIQUE_A >,
public OBSERVER_BASE< X, UNIQUE_B >,
public OBSERVER_BASE< Y, UNIQUE_C >
{
virtual void notify ( X, type2type< UNIQUE_A > ) override
{
std::cout << "x from Subject_A" << std::endl;
}
virtual void notify ( X, type2type< UNIQUE_B > ) override
{
std::cout << "x from Subject_B" << std::endl;
}
virtual void notify ( Y, type2type< UNIQUE_C > ) override
{
std::cout << "y from Subject_C" << std::endl;
}
};
int main ( int argc, char **argv )
{
Subject_A sub_a {};
Subject_B sub_b {};
Subject_C sub_c {};
Observer obs {};
sub_a.my_observer.insert( &obs );
sub_b.my_observer.insert( &obs );
sub_c.my_observer.insert( &obs );
sub_a.do_notify();
sub_b.do_notify();
sub_c.do_notify();
}
Is there a way to do it in this style ( without manual unique argument )? 有没有办法以这种方式做到这一点(没有手动的唯一参数)? I know sounds strange...
我知道听起来很奇怪......
template<class T>
struct SUBJECT_BASE
{
typedef AUTOMATIC_UNIQUE_TYPE__OR__WHAT_EVER unique_type;
};
class Subject_A : public SUBJECT_BASE< X > {};
class Subject_B : public SUBJECT_BASE< X > {};
class Subject_C : public SUBJECT_BASE< Y > {};
I don't think there's a way to achieve what you are asking for, but it's possible to achieve what you seem to want. 我认为没有办法实现你所要求的东西,但它有可能实现你想要的东西。 This implementation doesn't need the manual
UNIQUE_TYPE
: 此实现不需要手动
UNIQUE_TYPE
:
template<class T>
class Subject
{
std::vector<std::function<void(T)>> observers;
public:
void do_notify () {
for ( auto& obs : observers )
obs( T{} );
}
void add_listener(std::function<void(T)> l) {
observers.emplace_back(std::move(l));
}
};
class X {};
class Y {};
int main ()
{
Subject<X> sub_a {};
Subject<X> sub_b {};
Subject<Y> sub_c {};
sub_a.add_listener([](X){std::cout << "x from Subject_A" << std::endl;});
sub_b.add_listener([](X){std::cout << "x from Subject_B" << std::endl;});
sub_c.add_listener([](Y){std::cout << "y from Subject_C" << std::endl;});
sub_a.do_notify();
sub_b.do_notify();
sub_c.do_notify();
}
But it's substantially less OOP-ey than your posted code. 但它比你发布的代码少得多。 ( Live at Coliru )
( 住在Coliru )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.