Да предположим, че имам class A
шаблон, както следва:
template<typename T>
class A
{
T data;
public:
void func(){} //concerned function ** see here **
};
Сега имам друг class B
шаблон, да речем като
template<typename U>
class B
{
// ... something whatever
};
Това означава, че условието да не се конструира функцията е, че е непосредственият шаблон typename T
е B
, И C
може да бъде всеки тип, включително A
и B
.
Отговори:
2 за отговор № 1Функциите на членовете на класните шаблони не се генерират, освен ако не са използвани. Това е част от силата на механизма.
Ако искате да ограничите използването на тази функция на член, тогава наистина ще използвате
std::is_same
, Номерът е да се определи съответната черта / мета-функция:template<class, template<class...> class> struct is_template_instance : std::false_type {}; template<template<class...> class T, class... Cs> struct is_template_instance<T<Cs...>, T> : std::true_type {};
Истинската специализация ще бъде избрана само за нещо подобно
is_template_instance<std::vector<int>, std::vector>
, Сега просто го използвайте, или статично твърдение илиstd::enable_if
:auto func() -> typename std::enable_if<!is_template_instance<T, B>::value>::type { }
1 за отговор № 2
Ти трябва да частично специализирани шаблонът:
template<typename C>
class A<B<C>> // Used when A<B<C>> is instantiated
{
B<C> data;
};
Единственият недостатък на това е, че това изисква известно дублиране на кода, което не винаги е възможно.
Вместо това можете да създадете базов клас с цялата функционалност и да получите от тази база:
// Base class with all the common functionality.
template<typename T>
class A_impl
{
protected:
T data;
};
// Special case when "func" is available.
template<typename T>
class A : public A_impl<T>
{
public:
void func() {}
};
// Another special case where "func" is not available.
template<typename C>
class A<B<C>> : public A_impl<B<C>> {
};