2011-12-23 64 views
2

我有具有n個成員變量的一類T,帶值替換成員變量,例如C++從其他類型

class T{ 
    ushort name; 
ushort id; 
double value; 
.....etc... 
}; 

我也有類T1的集合,T2 ...,每個由構件的變量 它們是T的成員變量的子集(因爲沒有更好的單詞,讓我叫 這是T的子集類型)。例如,T1可以是

class T1 { 
ushort name; 
double value; 
}; 

剛剛拾取T.

的兩個成員

我想寫一個方法

template <typename X> 
T join(T t, X x) 

在那裏我們返回一個類類型T的,由用t代替每個成員變量的值,用 代替x的值(提供的X是T的一個子類型),t的其他值保持不變。

我可以考慮通過專業化來做到這一點。但是,應該有一個優雅的方法來做到這一點(也許可以檢測出X類型是T的子集類型並做正確的事情)。

回答

0

我可以考慮通過專業化來做到這一點。但是,應該有一個優雅的方法來做到這一點(也許可以檢測出X類型是T的子集類型並做正確的事情)。

「檢測」是專業化的一部分。您應該爲「子集」類型提供專門化,並且不提供通用專業化的實現(當某人使用其他類型的方法時引發編譯錯誤)。

0

如果您不想爲所有子集類型提供專門化。如果您使用的是MSVC,則可以嘗試使用成員檢測器慣用語:Member Detector__if_exist。 所以你只需要編寫* [在T成員人數2個宏(如果使用的MSVC,你不需要一些SetXXX),而不是

CREATE_MEMBER_DETECTOR(name); 
CREATE_MEMBER_DETECTOR(id); 
CREATE_MEMBER_DETECTOR(value); 
...... 

template<int N, typename T, typename R> 
class SetName 
{ 
public: 
    void operator()(T& t, R& r) 
    { 
    } 
}; 

template<typename T, typename R> 
class SetName<1, T, R> 
{ 
public: 
    void operator()(T& t, R& r) 
    { 
     t.name = r.name; 
    } 
}; 
...... 
(can be macros too) 

而且專業成員的所有可能的組合T中

join()方法應該是:

template <typename SUBSET> 
T join(T t, SUBSET x) 
{ 
    SetName<Detect_name<SUBSET>::value, T, SUBSET>()(t, x); 
    SetValue<Detect_value<SUBSET>::value, T, SUBSET>()(t, x); 
    ...... 

    return t; 
} 
0

試試這個:

#include <iostream> 
#include <typeifo> 

using namespace std; 

template<typename T> 
struct SetBase 
{ 
    T first; 
    T second; 
    SetBase(const T& first = T(), const T& second = T()) 
    : first(first), second(second) {} 
}; 

template<typename T> 
struct Set : public SetBase<T> 
{ 
    short name_id; 
    Set(const T& first = T(), const T& second = T(), const short& name) : 
    SetBase<T>(first, second), name_id(name){} 
}; 

template<typename Class, typename BaseClass> 
Class* join(Class **a, BaseClass *b) 
{ 
    if(typeid(Class) != typeid(BaseClass)) 
    { 
     Class* retval = new Class(*static_cast<Class*>(b)); 
     retval->name_id = (*a)->name_id; 
     *a = retval; 
    } 
    else 
    { 
     Class* retval = new Class(*b); 
     *a = retval; 
    } 
    return retval; 
} 

int main() 
{ 
    Set<int> *a = new Set<int>(1, 2, 3); 
    SetBase<int> *b = new SetBase<int>(4, 5); 
    cout << join(&a, b)->first << " " << join(&a, b)->second << " " << join(&a, b)->name_id << "\n"; 
    cout << a->first << " " << a->second << " " << a->name_id << "\n"; 

    return 0; 
} 

的設置類是公共從SetBase得來,所以我用中投是否有效

+0

傳遞給join()時,這是行不通的SubSetClass – 2012-04-18 16:33:04

0

我將實現從T1 ... Tn到T(或從T派生的某個類,並且具有實際設置的成員信息)的轉換,然後以T的形式實現join()函數。不要以爲這實際上是模板魔法的好地方