2011-12-23 111 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()函数。不要以为这实际上是模板魔法的好地方