Avoid angle brackets in default template
Asked Answered
K

3

10

If I have a template class with a default template type, I have to write the template angle brackets. Is it somehow possible to avoid this?

Example:

template <typename T=int>
class tt {
public:
  T get() { return 5; }
};

...

tt<> t;  // how to avoid <>
std::cout << t.get() << std::endl;

Until now i've did this by a separate namespace and redeclaring the class:

namespace detail_ {
template <typename T=int>
class tt {
public:
  T get() { return 5; }
};
}

class tt : public detail_::tt {}

...

tt t;
std::cout << t.get() << std::endl;

The problem is, if I want to use the class with an other type I have to go over namespace detail_. Is there another solution, which I didn't see yet.

Keppel answered 15/4, 2013 at 12:5 Comment(3)
what is the problem with <>? Having both tt and tt<Foo> being valid types is impossible afaik.Dragone
@ArneMertz the problem is just the style.Keppel
So what's the problem with that style? ;-)Dragone
L
3

Since C++17, because of class template argument deduction, things have changed.

tt and tt<> are not the same thing: types and class templates were different and continue to be treated differently.

Anyway in simple scenarios like the one in your example, C++17 assumes what you mean and the <> aren't needed anymore.

Further details:

Lilithe answered 18/3, 2019 at 11:21 Comment(0)
P
8

... if I want to use the class ...

This is a common source of confusion. A class template is not a class, but a template from which classes are generated. The angle brackets is what tells the compiler that you want to generate a class out of the class template with the given template arguments, without the angle brackets what you have is a template.

template <typename T = int>
struct TemplateClass { /*...*/ };

template <template <typename>  class T>
void f() {
   T<int> t; // ...
}
template <typename T>
void g() {
   T t; // ...
}

f<TemplateClass>();     // Accepts a template with a single type argument
g<TemplateClass<> >();  // Accepts a type, that can be generated out of the template

The language does not allow the coexistence of a template and a type with the same name in the same namespace, so the answer is that it cannot be done. You can create a type alias but you will have to give it a different name.

Pyroxenite answered 15/4, 2013 at 12:21 Comment(1)
David, thank you for your good answer, it served well for the past few years. But since C++17 I think the answer by @manlio does suite better. Therefor I switched the accepted answer.Keppel
C
6

You can use typedef...

typedef tt<> tt_;

And then simply use tt_.

Calliope answered 15/4, 2013 at 12:6 Comment(2)
Hm. that typedef saves you one character to type for every time you would use tt<>. The typedef itself, including spaces and the newline at its end, take 18 characters to type. Plus the loss of readability, since it's clear that tt<> is related to the template, but tt_ might be something different. You still cannot use the same name for the template and its default instantiation. So is it worth it? ;)Dragone
How's about typedef detail_::tt<> tt'?Bottomless
L
3

Since C++17, because of class template argument deduction, things have changed.

tt and tt<> are not the same thing: types and class templates were different and continue to be treated differently.

Anyway in simple scenarios like the one in your example, C++17 assumes what you mean and the <> aren't needed anymore.

Further details:

Lilithe answered 18/3, 2019 at 11:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.