Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do two structures with same name and with different Template arguments work

Why does only first implementation work and not the other implementations specified below, Can someone explain the way this template structure work and why others do not.

Template structures that work

template <typename T, typename U>
struct is_same
{
    static const bool value = false;
};

template <typename T>
struct is_same<T, T>
{
   static const bool value = true;
};

Template structures that do not work

template <typename T, typename U>
struct is_same<T, U>
{
   static const bool value = false;
};

template <typename T>
struct is_same<T, T>
{
  static const bool value = true;
};

One more that does not work

template <typename T, typename U>
struct is_same<T,U>
{
   static const bool value = false;
};

template <typename T>
struct is_same
{
   static const bool value = true;
};

And the Main Function

template <class A, class B>
bool IsSameClass() {
  return is_same<A, B>::value;
}
int main()
{
  bool ret =    IsSameClass<P,C>();
}
like image 725
user2256825 Avatar asked Mar 22 '16 16:03

user2256825


2 Answers

You always start with a template definition:

template <class T, class U>
class is_same { ... };

Or, as Jarod42 reminded me, with a declaration:

template <class T, class U> class is_same;

Once there's a template, you can define a partial specialization by refining one or more of the template arguments, as in your example:

template <class T>
class is_same<T, T> { ...};

The specialization still takes two arguments, just like the original template, but they're the same type, so there's only one type name in the template <...> part of the definition.

In use, is_same<int, double> would match the template definition; is_same<int, int> would match the partial specialization.

You can also specify a full specialization. Not that you'd want to here, but following on with this example:

template <>
class is_same<void, void> { ... };

This would match, obviously, is_same<void, void>.

The reason that the other two attempts don't work is that neither of them has a template definition, only things that look like specializations. Without a definition there's nothing to specialize.

Note that this is a bit of an oversimplification. It's intended to address "why don't these things work", not "how can I specialize a template".

like image 170
Pete Becker Avatar answered Oct 22 '22 00:10

Pete Becker


The syntax

template <typename T, typename U>
struct is_same<T, U>
{
   static const bool value = false;
};

is used to create a specialization of a class template. In order to do that, you have to first declare the template or create its generic definition first.

template <typename T, typename U> struct is_same;

or

template <typename T, typename U>
struct is_same
{
   static const bool value = false;
};

Even if you did that,

template <typename T, typename U>
struct is_same<T, U>
{
   static const bool value = false;
};

is not a valid specialization since there is no way to decide which template to use when instantiated with is_same<int, float>.

Templates cannot be overloaded by using:

template <typename T, typename U>
struct is_same
{
   static const bool value = false;
};

template <typename T>
struct is_same
{
   static const bool value = true;
};

The language simply does not allow that.

like image 1
R Sahu Avatar answered Oct 22 '22 02:10

R Sahu