Template default arguments

C++Templates

C++ Problem Overview


If I am allowed to do the following:

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

Why am I not allowed to do the following in main?

Foo me;

But I must specify the following:

Foo<int> me;

C++11 introduced default template arguments and right now they are being elusive to my complete understanding.

C++ Solutions


Solution 1 - C++

Note:

Foo me; without template arguments is legal as of C++17. See this answer: https://stackoverflow.com/a/50970942/539997.

Original answer applicable before C++17:

You have to do:

Foo<> me;

The template arguments must be present but you can leave them empty.

Think of it like a function foo with a single default argument. The expression foo won't call it, but foo() will. The argument syntax must still be there. This is consistent with that.

Solution 2 - C++

With C++17, you can indeed.

This feature is called class template argument deduction and add more flexibility to the way you can declare variables of templated types.

So,

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

int main() {
    Foo f;
}

is now legal C++ code.

Solution 3 - C++

You are not allowed to do that but you can do this

typedef Foo<> Fooo;

and then do

Fooo me;

Solution 4 - C++

You can use the following:

Foo<> me;

And have int be your template argument. The angular brackets are necessary and cannot be omitted.

Solution 5 - C++

Somewhat different case and rather later but where a template function is involved. gcc 11.2 can't seem to compile this:

template <typename T = int>
struct Test {};
template<typename T> void foo(T& bar) {}
int main()
{
    Test t;
    foo<Test>(t);
}

but has no problem with

template <typename T = int>
struct Test {};
template<typename T> void foo(T& bar) {}
int main()
{
    Test t;
    foo<Test<>>(t);
}

Of course

template <typename T = int>
struct Test {};
template<typename T> void foo(T& bar) {}
int main()
{
    Test t;
    foo(t);
}

works - but sometimes you need to explicitly force the type. Is this a compiler bug?

Solution 6 - C++

As per the C++17 Standard, template arguments are necessary to be passed.

But if you still want a way around this, you can use using keyword like this

template <typename T>
class Foo{
};
using IFoo=Foo<int>

Or, you can also use preprocessor like this

template <typename T>
class Foo{
};

#define IFoo Foo<int>

Quick Reminder > Preprocessors are bad for debugging.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser633658View Question on Stackoverflow
Solution 1 - C++Joseph MansfieldView Answer on Stackoverflow
Solution 2 - C++Paolo MView Answer on Stackoverflow
Solution 3 - C++g24lView Answer on Stackoverflow
Solution 4 - C++Andy ProwlView Answer on Stackoverflow
Solution 5 - C++RadrichView Answer on Stackoverflow
Solution 6 - C++Yogesh AggarwalView Answer on Stackoverflow