Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I specialize a class template with an alias template?

Here's a simple example:

class bar {};

template <typename>
class foo {};

template <>
using foo<int> = bar;

Is this allowed?

like image 694
R. Martinho Fernandes Avatar asked Oct 18 '11 00:10

R. Martinho Fernandes


People also ask

What is an alias template?

Alias templates are a way to give a name to a family of types. Template parameters can be types, non-types, and templates themselves.

What is function template specialization?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.

What is alias declaration in C++?

You can use an alias declaration to declare a name to use as a synonym for a previously declared type. (This mechanism is also referred to informally as a type alias). You can also use this mechanism to create an alias template, which can be useful for custom allocators.

Why does the need of template specialization arise?

It is possible in C++ to get a special behavior for a particular data type. This is called template specialization. Template allows us to define generic classes and generic functions and thus provide support for generic programming.


2 Answers

$ clang++ -std=c++0x test.cpp
test.cpp:6:1: error: explicit specialization of alias templates is not permitted
template <>
^~~~~~~~~~~
1 error generated.

Reference: 14.1 [temp.decls]/p3:

3 Because an alias-declaration cannot declare a template-id, it is not possible to partially or explicitly specialize an alias template.

like image 128
Howard Hinnant Avatar answered Sep 30 '22 03:09

Howard Hinnant


Although direct specialization of the alias is impossible, here is a workaround. (I know this is an old post but it's a useful one.)

You can create a template struct with a typedef member, and specialize the struct. You can then create an alias that refers to the typedef member.

template <typename T>
struct foobase {};

template <typename T>
struct footype
  { typedef foobase<T> type; };

struct bar {};

template <>
struct footype<int>
  { typedef bar type; };

template <typename T>
using foo = typename footype<T>::type;

foo<int> x; // x is a bar.

This lets you specialize foo indirectly by specializing footype.

You could even tidy it up further by inheriting from a remote class that automatically provides the typedef. However, some may find this more of a hassle. Personally, I like it.

template <typename T>
struct remote
  { typedef T type; };

template <>
struct footype<float> :
  remote<bar> {};

foo<float> y; // y is a bar.
like image 43
Aotium Avatar answered Sep 30 '22 02:09

Aotium