2010-11-11 2 views
4

У меня есть класс шаблонов, который имеет множество функций, но по существу является классом векторов. Я хочу добавить одну функцию только к типу bool.Специализация функции члена класса шаблона только для одного типа

#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() к частному случаю отраженного класса, который является единственным случаем, когда это будет иметь смысл. Каков наилучший способ сделать это. компилятор, похоже, не любит добавлять, который() отражается и только определяет его для bool.

ответ

12

Вы можете определить его в шаблоне класса, как этот

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>()); } 
}; 

Это дает компиляции ошибки времени, если вы звоните which на reflected<T> для которого T вы не дали надлежащего определения.

+0

Я не уверен, хочет ли он, чтобы метод потерпел неудачу или просто он не определен *, но для * 'bool'. Во всяком случае, ваше решение очень приятно :) –

+0

Как это соотносится с ответом Джона Диблинга? Есть ли преимущество, обеспечиваемое дополнительной «косвенностью»? Спасибо – icecrime

+0

@icecrime вам не нужно дублировать конструкторы, и он масштабируется. Если какая-то функция имеет смысл только для 'int', а не для других, вам не нужен другой производный класс. Мне нравится использовать перегрузку для этого. –

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' за то, что бил меня на 90 секунд! – sbi

+0

Вам нужно '' для reflection_base также в декларации отраженного. Но почему, зачем вам нужно Reflection_base? –

+0

@ Diego: так, что основной шаблон «отраженный» и каждая специализация «отраженного» могут использовать одни и те же элементы. –

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! но я бы описал это как «добавление, которое() отражало и определяло только для bool». это то, что OP говорит, что он делает. –

+0

Я интерпретировал описание ОП, как будто она пыталась переопределить класс для специализации 'bool'. –

+0

После повторного чтения вы можете быть правы. Если OP ответит, что это то, что он делал, я удалю его. –

0

Вы можете добавить vector<ar_index> reflected<bool>::which() в reflected<bool> (и только ему, а не к общему шаблону). Если вы получите сообщение об ошибке, возможно, вы не делаете специализацию шаблона правильно ...

Смежные вопросы