2015-04-30 4 views
2

рассмотрите этот код.Функция вызова функции класса шаблона. C++

template<class T> 
class A 
{ 
    public: 
     void f(){..} 
     void h(){..} 
}; 


template<> 
class A<int> 
{ 
    public: 
     void f(){// something different..} 
     //void h(){..} 
}; 

int main() 
{ 
    A<int> obj; 
    obj.h(); // I want to call A<T>::h(), but compiler erred that there is no h function in A<int> 
} 

Есть ли способ этого звонка ?? Или какое-то обходное решение?

+3

Компилятор верен. Вы можете поместить функцию 'h' в другое место, например. базовый класс. – interjay

+0

@Eduard Rostomyan Как вы собираетесь называть это, если его не существует? –

+0

@ VladfromMoscow, я хочу называть комод :: h(), я не знаю, как, если бы знал, что я скорее задаю этот вопрос. –

ответ

3

A<T> - шаблон шаблона, который вводит семейство классов A на основе любых типов: T. A<int> - это явная специализация A<T> - он заменяет определение общего класса. Это ничем не отличается от того, написано:

class Aint { 
public: 
    void f(); 
}; 

Эта специализация имеет только одну функцию-член - f. Поэтому, когда вы пытаетесь сделать это:

A<int> obj; 
obj.h(); 

Это не компилируется, потому что A<int> не имеет функцию-член с именем h. Несмотря на то, что оба названы A, A<int> и A<T> не связаны друг с другом - один не является базовым классом другого, и не имеет значения, какие функции и члены существуют в общем A<T> - специализация A<int> не имеет их.

Если h нечто общее, вы можете переместить его в базовый класс:

struct ABase { // or alternatively ABase<T> 
    void h(); 
} 

template <typename T> 
class A : ABase { 
    void f(); 
}; 


template <> 
class A<int> : ABase { 
    void f(); 
}; 

Таким образом, все инстанциаций A будет иметь h(). То есть, пока кто-то идет дальше и добавляет:

template <> 
class A<char> // no inheritance 
{ 
    // no h() 
}; 
2

В зависимости от того, сколько материала вы меняете в вашей специализации, вы могли бы быть лучше только специализирующимся f для A<int>, а не Специализируя весь класс:

template<class T> 
class A 
{ 
    public: 
     void f(){cout << "standard";} 
     void h(){cout << "standard";} 
}; 

template<> 
void A<int>::f() {cout << "specialized";} 

int main() 
{ 
    A<bool>{}.f(); //outputs standard 
    A<int> obj; 
    obj.f();  //outputs specialized 
    obj.h();  //outputs standard 
} 

Если ваша специализация является более сложной, чем вы может вывести общее поведение в базовый класс и извлечь из него A.

2

Этот код работает для меня:

template<class T> 
class BaseA { 
public: 
    void f(){...} 
    void h(){...} 
}; 

template<class T> 
class A : public BaseA<T> 
{ 
}; 


template<> 
class A<int> : public BaseA<int> 
{ 
    public: 
     void f(){...} 
     //void h(){..} 
}; 

int main() 
{ 
    A<int> obj; 
    obj.h(); // I want to call A<T>::h(), but compiler erred that there is no h function in A<int> 
} 

Он объявляет базовый класс, который наследуется от обоих.