1
我試圖定義一個類模板,它可以在許多數據結構上執行一些輸入/輸出操作(通過運算符< <和>>來自另一個類)。模板類的隱式轉換
總之,我可以做例子:
vector<int> x;
map<string,vector<vector<int>>> y;
const int z = 42;
FooStream fs;
Foo<decltype(x)> fx(x);
Foo<decltype(y)> fy(y);
Foo<decltype(z)> fz(z);
fs << fx << fy <<fz>> fy >> fx;
我的問題是如何能達到這樣的:
vector<int> x;
map<string,vector<vector<int>>> y;
const int z = 42;
FooStream fs;
fs << x << y <<z>> y >> x;
//error : no operator found which takes a right-hand operand of type 'std::vector<_Ty>' (or there is no acceptable conversion)
FooStream ::運算< <和>>應該接受過類型T當專業化Foo < T>被定義時。
欲瞭解更多詳情,這是我的(簡體)代碼。
class FooBase1{
protected:
union p_type{const void *p1;void *p2;} p;
public:
FooBase1(const void *v){p.p1 = v;};
virtual void func1_() = 0;
};
class FooBase2 : public FooBase1{
public:
FooBase2(void *v) : FooBase1(v){};
virtual void func2_() = 0;
};
template<typename T,typename Enable=void>
class Foo{
public:
typedef void generic;
};
template<typename T,typename E=void> struct is_generic : std::false_type{};
template<typename T> struct is_generic<T,typename Foo<T>::generic> : std::true_type {};
template<typename T,typename T2=void> struct enable_if_ng : enable_if<!is_generic<T>::value,T2> {};
template<typename T> struct get_foo_type {};
template<typename T> struct get_foo_type<Foo<T> > {typedef T type;};
#define DECLARE_FOO_SPECIALIZATION(Type)\
template<>\
class Foo<Type> : public FooBase2{\
public:\
Foo(Type &v) : FooBase2(&v){}\
virtual void func1_(){func1(*(const Type *)p.p2);}\
virtual void func2_(){func2(*(Type *)p.p2);}\
static void func1(const Type&){/*user defined*/}\
static void func2(Type&){/*user defined*/}\
};
//friend FooStream& operator>>(FooStream& fs,Type &f){Foo<Type>(f).func2_();return fs;} doesn't work
DECLARE_FOO_SPECIALIZATION(bool)
DECLARE_FOO_SPECIALIZATION(int)
DECLARE_FOO_SPECIALIZATION(long)
DECLARE_FOO_SPECIALIZATION(float)
DECLARE_FOO_SPECIALIZATION(double)
DECLARE_FOO_SPECIALIZATION(string)
template<typename T1>
class Foo<vector<T1>,typename enable_if_ng<T1>::type> : public FooBase2{
public:
Foo(vector<T1> &v) : FooBase2(&v){}
virtual void func1_(){func1(*(const vector<T1> *)p.p2);}
virtual void func2_(){func2(*(vector<T1> *)p.p2);}
static void func1(const vector<T1>&){/*user defined*/}
static void func2(vector<T1>&){/*user defined*/}
};
template<typename T1,typename T2>
class Foo<map<T1,T2>,typename enable_if<!is_generic<T1>::value && !is_generic<T2>::value>::type> : public FooBase2{
public:
Foo(map<T1,T2> &v) : FooBase2(&v){}
virtual void func1_(){func1(*(const map<T1,T2> *)p.p2);}
virtual void func2_(){func2(*(map<T1,T2> *)p.p2);}
static void func1(const map<T1,T2>&){/*user defined*/}
static void func2(map<T1,T2>&){/*user defined*/}
};
template<typename T1>
class Foo<const T1,typename enable_if_ng<T1>::type> : public FooBase1{
public:
Foo(const T1 &v) : FooBase1(&v){}
virtual void func1_(){func1(*(const T1 *)p.p1);}
static void func1(const T1& v){Foo<T1>::func1(v);}
};
class FooStream{
public:
FooStream(){};
FooStream& operator<<(FooBase1 &f){f.func1_();return *this;};
FooStream& operator>>(FooBase2 &f){f.func2_();return *this;};
};
(其他問題:我可以通過使用模板漂亮的東西取代我的宏DECLARE_FOO_SPECIALIZATION我應該改變我的類層次?)
謝謝。
也許你可以嘗試使用括號來命令評估。 – 0x499602D2 2013-04-23 23:15:55
帖子名稱需要修復。這與帖子無關。 – 2013-04-23 23:22:56
@ 0x499602D2:運營商<< and >>從左至右進行評估。但是當我只輸入1個參數時,我有相同的錯誤信息。 – Gilles 2013-04-23 23:42:40