7

I declare a templated class with all parameters having default arguments, for example:

template<typename TYPE = int>
class Foo {};

Then the following two are equivalent:

Foo<int> one;
Foo<> two;

However, I'm not allowed to just do:

Foo three;

Is it possible to achieve that with a typedef to the same name but without the brackets, like this:

typedef Foo<> Foo;
Alan Turing
  • 12,223
  • 16
  • 74
  • 116

6 Answers6

8

I do something like the following, I don't know if you will like it or not:

template<typename TYPE = int>
class basic_Foo {};

typedef basic_Foo<int> Foo;
Cem Kalyoncu
  • 14,120
  • 4
  • 40
  • 62
  • 4
    aka "the stdlib approach". :) – Xeo Jun 11 '11 at 15:17
  • 1
    Yes, the same thing happened with `basic_string` and friends :) – rubenvb Jun 11 '11 at 15:18
  • So you would do that if `basic_Foo` is used a lot more than any other `basic_Foo`? The reason I ask is because it seems like an excessive number of characters to add to a class name, as opposed to: `typedef Foo Foo_int` or something like that. – Alan Turing Jun 11 '11 at 15:32
  • @Lex He was trying to replace *entire* definition with its name, I assume he is not planning to use it with another type. In your case, using basic_ would not help. – Cem Kalyoncu Jun 11 '11 at 15:35
2

You can't redeclare a symbol with a different type, so whatever you will be able to do won't work as you expect. If you want to achieve this, use a different name as alias :

typedef Foo<> Foo_;
Jaffa
  • 12,442
  • 4
  • 49
  • 101
1
typedef Foo<> Foo;

Gives:

prog.cpp:4: error: ‘typedef class Foo<int> Foo’ redeclared as different kind of symbol
prog.cpp:2: error: previous declaration of ‘template<class TYPE> class Foo’

The error pretty much tells what the problem is. Compiler sees Foo as being re-declared.

However, this shall compile and work:

template<typename TYPE = int> class Foo {};

typedef Foo<> FooClone;

int main()
{
   Foo<int> one;
   Foo<> two;
   FooClone three;

   return 0;
}
Alok Save
  • 202,538
  • 53
  • 430
  • 533
1

No. Although you can declare a typedef for a class with the same name as a class because you can use a typedef to redefine a name to refer to the type to which it already refers.

typedef class A A;

or if A was already declared as a class:

typedef A A;

You can't do that with the name of a template (the name of a template isn't a name of a class), you'd have to give it a different name.

typedef Foo<> Bar;
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
1

If the declaration typedef Foo<> Foo; is allowed, thereafter the name Foo as a template cannot be specified. That is, the following becomes invalid.

template< template< class > class > struct A {...};
A< Foo > a; // error

Though the above typedef isn't allowed in practice, if you still need to write Foo as Foo<>, a macro like the following will meet the purpose.

#define Foo Foo<>
Ise Wisteria
  • 11,259
  • 2
  • 43
  • 26
  • 3
    May be too late but dont use define for this purpose. It will cause problems in many ways. You will NEVER be able to use foo with a different type. You will NEVER be able to use foo in another namespace. – Cem Kalyoncu Nov 13 '11 at 09:14
0

Unfortunately, no, because Foo is already the name for the class template itself, and thus can't be anything else in the same namespace.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Xeo
  • 129,499
  • 52
  • 291
  • 397