Reputation:
Suppose I have a class A
template as follows:
template<typename T>
class A
{
T data;
public:
void func(){} //concerned function ** see here **
};
Now I have another class B
template, say as
template<typename U>
class B
{
// ... something whatever
};
That means the condition for not constructing the function is that the immediate template typename T
is B
. And C
can be any type including A
and B
.
Upvotes: 0
Views: 943
Reputation: 170239
Member functions of class templates aren't generated unless they are odr-used. This is part of the mechanism's strength.
If you want to constrain the use of this member function, then you would indeed use std::is_same
. The trick is to define the appropriate trait/meta-function:
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 {};
The true specialization will only be chosen for something like is_template_instance<std::vector<int>, std::vector>
. Now just put it to use, either static assert or std::enable_if
:
auto func() ->
typename std::enable_if<!is_template_instance<T, B>::value>::type {
}
Upvotes: 2
Reputation: 49028
You need to partial specialize the template:
template<typename C>
class A<B<C>> // Used when A<B<C>> is instantiated
{
B<C> data;
};
The only downside on this is that this requires some code duplication, which is not always possible.
Instead, you can create a base class with all the functionality, and derived from that base:
// 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>> {
};
Upvotes: 1