Can I specialize a class template with an alias template?
Asked Answered
F

3

14

Here's a simple example:

class bar {};

template <typename>
class foo {};

template <>
using foo<int> = bar;

Is this allowed?

Flyboat answered 18/10, 2011 at 0:38 Comment(8)
How is this different from typedef foo<int> bar;?Splotch
@KerrekSB: It's the complete opposite. This would be more like typedef bar foo<int>; (though this is not allowed). In my example, bar already exists as a type, and foo<int> becomes a new name for it. (What you wrote is equivalent to using bar = foo<int>;, if that helps.)Flyboat
Oh, I see. But then you might as well ask for any class definition to be copyable: class Foo = Bar; etc. I don't suppose that's possible...Splotch
using Foo = Bar;? (Or typedef Bar Foo;, if you prefer the old style.) I don't expect my example (if valid) to create a distinct type (please let me know I'm misunderstanding you).Flyboat
Hmm, reading this answer: #6622952 makes me believe this is indeed not possible.Flyboat
Interesting. I was thinking about copying the type definition, not just aliasing, since I imagine that you'd have to provide (the equivalent of) a full class definition for an explicit specialization. The linked answer does indeed suggest that aliases are not the right tool for the job.Splotch
I wrote a few defines that generalize on Aotium's answer, here https://mcmap.net/q/368541/-alias-template-specialisationUnpaged
There is slightly indirect way. see Section 1.4Eighth
E
11
$ 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.

Epicalyx answered 18/10, 2011 at 1:1 Comment(1)
Is that clang 3.0? OK I see from the clang pages that my clang 2.9 won't work.Brno
M
11

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.
Monoacid answered 19/3, 2012 at 11:38 Comment(3)
I have been using this trick, but it does help to have it out here. So, thanks for putting it up. And welcome to StackOverflow!Flyboat
Just after writing a long answer with workaround for this limitation, I found your answer that uses the same principle. In any case I wrote in addition a couple of defines to make the code shorter. Take a look if you are interested: https://mcmap.net/q/368541/-alias-template-specialisationUnpaged
I think you missed a <T> in the using statement: template <typename T> using foo = typename footype<T>::type;Oxfordshire
F
7

According to §14.7.3/1 of the standard (also referred to in this other answer), aliases are not allowed as explicit specializations :(

An explicit specialization of any of the following:

  • function template
  • class template
  • member function of a class template
  • static data member of a class template
  • member class of a class template
  • member class template of a class or class template
  • member function template of a class or class template

can be declared[...]

Flyboat answered 18/10, 2011 at 0:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.