Template default arguments
C++TemplatesC++ 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);
}
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.