2010-11-11 134 views
4

我有一个有很多功能,但本质上是一个向量类模板类。我想添加一个函数只是布尔类型。专业模板类成员函数只有一种类型的

#include <vector> 
template <typename T> 
class reflected{ 
    private: 
     T*dev_; 
     T*host_; 
     ar_size size; 
     reflected<T>& operator=(reflected<T>& rhs);//do not impliment. assign not allowed. 
     reflected(reflected<T>& old); //do not impliment. Copy not allowed. 
    public: 
     reflected():size(0L),dev_(NULL),host_(NULL){} 
     reflected(ar_size n):size(n),dev_(NULL),host_(NULL){init();} 
     reflected(const T*x,ar_size n):size(n),dev_(NULL),host_(NULL){init();set(x);} 
     ~reflected(); 
     void init(); 
     void init(ar_size n); 
     void init(const T*x,ar_size n); 
     void set(const T * x); 
     void setat(ar_index i, T x); 
     const T getat(ar_size i); 
     const T * devPtr(); 
     const T operator [](const ar_index i); 
     ar_size length(){return size;} 
}; 

我想一个函数vector<ar_index> reflected<bool>::which()增加反射类,这是它将使意义的唯一个案的特殊情况。做这个的最好方式是什么。编译器似乎不喜欢添加which()来反射,只为bool定义它。

回答

12

,如果你对他们T你没有给予适当的定义中reflected<T>which您可以在类模板定义它像这样

template <typename T> struct id { typedef T type; }; 

template <typename T> 
class reflected{ 
    private: 
     /* ... */ 
     vector<ar_index> which(id<bool>) { 
      /* ... */ 
     } 
    public: 
     /* ... */ 
     vector<ar_index> which() { return which(id<T>()); } 
}; 

这给出了一个编译时错误。

+0

我不确定他/她是否希望该方法失败或者只是它没有被定义*,而是用于*'bool'。无论如何,你的解决方案是非常好的:) – 2010-11-11 21:39:52

+0

这与John Dibling的答案相比如何?额外的“间接”是否有任何优势?谢谢 – icecrime 2010-11-11 21:50:42

+0

@icecrime你不需要重复构造函数,它可以缩放。如果某个函数只对'int'有意义而对其他函数没有意义,则不需要另一个派生类。我喜欢为此使用重载。 – 2010-11-11 22:04:21

4

如果你想添加只有一个问题,你可以与专业化相结合的产业,

template <typename T> 
class reflected_base { 
    // your current 'reflected' contents go here 
}; 

template <typename T> 
class reflected : public reflected_base { }; 

template <> 
class reflected<bool> : public reflected_base { 
    vector<ar_index> which(); 
}; 

这种方法的缺点是,你必须重新实现某些操作(析构函数,拷贝构造函数等)每个专业。另一种选择是:

template <typename T> 
class specialized_reflected { }; 

template <> 
class specialized_reflected<bool> { 
public: 
    vector<ar_index> which(); 
}; 

template <typename T> 
class reflected : public specialized_reflected<T> { 
    // your current 'reflected' contents go here 
}; 

尽管如此,依赖名称查找仍然存在潜在的问题。第三个选项(可能是我选择的一个)将使用非成员函数:

vector<ar_index> which(reflected<bool>&); 
+0

'+ 1'由90secs打我! – sbi 2010-11-11 21:31:56

+0

你需要''为reflected_base也在声明中反映出来。但是,那么为什么你确实需要reflect_base? – 2010-11-11 21:33:46

+0

@Diego:所以主'反射'模板和'反射'的每个特化都可以使用相同的成员。 – 2010-11-11 21:34:53

1

不能按照你想要的方式直接完成。但是您可以通过不为任何类定义reflected()来获得类似的结果,除了专门的类。那么如果你尝试在一个不支持的类上使用它,你会得到一个班轮错误。

#include <string> 
#include <sstream> 
using namespace std; 

template<typename A> 
class Gizmo 
{ 
public: 
    Gizmo(){}; 
    int which();  
}; 

template<> int Gizmo<bool>::which() 
{ 
    return 42; 
} 

int main() 
{ 

    Gizmo<bool> gb; 
    gb.which(); 

    Gizmo<int> gi; 
    gi.which(); // LINKER ERROR for Gizmo<int>which() 

    return 0; 
} 
+0

snap!但我会将其描述为“添加which()来反映并仅为bool定义它。”这是OP说他在做什么。 – 2010-11-11 21:38:56

+0

我解释了OP的描述,好像她正试图重新定义这个类的'bool'专业化。 – 2010-11-11 21:41:51

+0

重新阅读后,您可能是对的。如果OP回应这是他正在做的,我会删除它。 – 2010-11-11 21:43:13

0

您可以将vector<ar_index> reflected<bool>::which()添加到reflected<bool>(并且仅限于它,而不是普通模板)。如果你得到一个错误,也许你没有做正确的模板特...