C++ template function default value
Try this:
template<class T> T sum(T a, T b, T c=T())
{
return a + b + c;
}
You can also put in T(5) if you are expecting an integral type and want the default value to be 5.
Data type of default value for template function argument different from instantiating data type
Shouldn't the Case 1 and Case 3 also fail, because the function
template is instantiated by int and the deafult value is of type
std::string?
No it shouldn't. See below for why. If you want it to fail then you should define f()
to be a regular function receiving an argument of type std::string
and not a function template.
What you have is a case of default argument instantiation, see here in [temp.inst]:
If a function template
f
is called in a way that requires a default
argument to be used, the dependent names are looked up, the semantics
constraints are checked, and the instantiation [...] is done as if the default argument had been an
initializer used in a function template specialization, [...] This analysis is
called default argument instantiation. The instantiated default
argument is then used as the argument off
.
When you write:
template <typename T>
void f(T x = std::string{""}){...}
it means that ""
is the default argument for x
only in case the call is made without any arguments. for example in your Case 2.
Your template function is defined to be instatiated just fine for either int
or various other types.
For example here (Case 1):
f(23);
It is instatiated implicitly (by inference base on the argument type) to be f<int>()
, as 23
is defined in the spec to be an int
literal. The parameter x
of type int
receives the non-default value of 23
which you have provided at the call site.
And here (Case 2):
f<int>();
is exactly where the standard clause above comes into play: You successfully instantiate f()
but no argument is provided for it, hence the instantiated default argument is then used as the argument of f
. So compilation fails as this default value here for parameter x
is defined to just be std::string
and no conversion applies from it to type int
. It is effectively equivalent to calling f("")
on a function declared void f(int x)
.
And here (Case 3):
f<int>(23);
Explicit again and this time you provide the right type of argument at the call site.
Default value for template function argument
Yes, default value is not considered in template arugment deduction.
Type template parameter cannot be deduced from the type of a function default argument
You can add an overload, e.g.
template <typename T>
void myFunc(int value, T mode)
{
...
}
void myFunc(int value) {
myFunc(value, mode1());
}
Template default arguments
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.
C++ function template using default parameters
Template parameters cannot be deduced from default arguments. C++11, [temp.deduct.type]§5:
The non-deduced contexts are:
- ...
- A template parameter used in the parameter type of a function parameter that has a default argument that is being used in the call for which argument deduction is being done.
- ...
You can get around this using overloading:
template <typename Object, typename Comparator>
const Object &findMax(const vector<Object> &arr, const Comparator &isLessThan)
{
int maxIndex = 0;
for (int i = 1; i < arr.size(); i++) {
if (isLessThan(arr[maxIndex], arr[i])) {
maxIndex = i;
}
}
return arr[maxIndex];
}
template <typename Object>
const Object &findMax(const vector<Object> &arr)
{
return findMax(arr, std::less<Object>());
}
Default parameter value in template function, depending on type
This is what I come up with:
template <typename T> struct default_trim_chars;
template<> struct default_trim_chars<std::string> {
static const char* value() { return " \n\r"; }
};
template<> struct default_trim_chars<std::wstring> {
static const wchar_t* value() { return L" \n\r"; }
};
template <typename Type> Type Trim ( const Type &In_String,
const Type &In_TrimCharacters = default_trim_chars<Type>::value()){
/* ... */
}
You can also declare value
as a data member instead of a function, but that would require constexpr
and C++11.
Default value for template with member function pointer
How do I make
&Foo::DoNothing()
the default forFunc(...)
?
You basically just specify the required default arguments:
struct Foo { int DoNothing() const { } };
template<
typename T,
typename C,
typename R = decltype(std::declval<const C>().DoNothing())
>
T Func(C const* obj,
R (C::*mf)() const = &C::DoNothing,
T* maybe_unused = nullptr)
{
(obj->*mf)();
return T{};
}
Note that you need to specify two different things: for one the default member function to call and additionally the default return value type, as it cannot be deduced from default arguments.
Default template parameter cannot be used inside another template parameter?
This:
DefaultType obj;
uses CTAD (class template argument deduction) which is available since C++17 and only in certain contexts:
- any declaration that specifies initialization of a variable and variable template
- new-expressions
- function-style cast expressions
- the type of a non-type template parameter:
To instantiate DefaultType
with the default argument in other contexts you still need to write DefaultType<>
.
I suppose the reason to have CTAD only in certain contexts is that those are the contexts where you always want an instantiation, but never the template.
Related Topics
How to Parse Mustache with Boost.Xpressive Correctly
What Should the 'Pop()' Method Return When the Stack Is Empty
C++ Difference Between 0 and 0.0
Boost::Spirit How to Parse and Call C++ Function-Like Expressions
How to Convert a Byte Array into Double in C
Sorting a List of a Custom Type
C++ "Hello World" Boost Tee Example Program
What Are the Reasons That Extending the Std Namespace Is Considered Undefined Behavior
How to Find Substring from String
Const and Non Const Template Specialization
How to Show Qsqlquerymodel in Qml
Win32 C/C++ Load Image from Memory Buffer
Understanding Lapack Calls in C++ with a Simple Example
Why How to Call a Non-Constexpr Function Inside a Constexpr Function
C++: Std::Move with Rvalue Reference Is Not Moving Contents
Check If Class Is Derived from a Specific Class (Compile, Runtime Both Answers Available)