2009-11-22 3 views
2

Рассмотрим следующий фрагмент кода:C++ Шаблоны против агрегации

class B { 
    private: 
    // some data members 
    public: 
    friend bool operator==(const B&,const B&); 
    friend ostream& operator<<(ostream&,const B&); 
    // some other methods 
}; 

template <typename T=B> 
class A { 
    private: 
    // some data members 
    vector<vector<T> > vvlist; 
    public: 
    // some other methods 
}; 

Моя требование заключается в том, что тип Т, который передается в качестве параметра типа должен обеспечить определения для оператора == и оператор < < методы. Я не хочу применять другие ограничения для T.

Как это сделать?

Один из способов, которым я могу думать, это создать абстрактный класс, который говорит «Z», который объявляет эти два метода.

, а затем написать

vector<vector<Z> > vvlist; 

и НЕ имеют класс А в качестве шаблона.

Есть ли лучший способ сделать это?

+1

Просто, чтобы быть ясным: если A использует эти операторы в любом месте, ваш код просто не будет компилироваться, если T не имеет их. Вы хотите сделать лучше, чем это? Кроме того, T также должен удовлетворять требованиям std :: vector - он должен быть выполнен с возможностью копирования. – UncleBens

+0

О! ОК. Тогда, возможно, этот пример не является проблемой. Но я просто представил их в качестве примеров, а не какую-то определенную функцию. – user855

ответ

4

Это происходит автоматически.

Если код вызывает операторы == и <<, тогда код просто не будет компилироваться, если классу передается тип, который не определяет эти операторы.

Это, по сути, утка-типизация. Если это похоже на утку, а quacks - как утка, то это утка. Не имеет значения, реализует ли он интерфейс IDuck, пока он предоставляет функции, которые вы пытаетесь использовать.

0

Вы можете написать частный метод в A, который будет проверять необходимый материал на T во время компиляции.

void TestReq(T x, T y) 
{ 
    if (x==y) 
    cout << x; 
} 

Таким образом, даже простые целые числа будут проходить и работать.

+1

Не совсем. Вы также должны вызвать этот метод, иначе он просто не может быть скомпилирован. То есть, просто имея это, все могло бы (будет) проходить. – UncleBens

3

Кажется, что вы ищете библиотеку проверки концепции. Посмотрите, что Boost может предложить: Boost Concept Check Library. Эта ссылка также имеет хорошее объяснение, каковы концепции. Цитата:

Концепция представляет собой набор требований (допустимых выражений, связанных типов, семантических инвариантов, сложность гарантий и т.д.), что тип должен выполнить, чтобы правильно использовать в качестве аргументов в вызове к родовому алгоритма

в вашем вопросе, понятие «тип T должен обеспечить operator== и operator<<».