template <typename T>
T go(T a, T *b){ T *t; return *t;}
int main() {
const int x = 10;
go(x, &x);
return 0;
}
Gives compiler error:
error: no matching function for call to ‘go(const int&, const int*)’
Why is the first argument a reference type const int&
instead of just const int
?
To fix this compilation error, I overrode the compiler deduction process by specifying the type of arguments go<const int>(x, &x);
, but again why do I need to do that?
Class Template Argument Deduction (CTAD) is a C++17 Core Language feature that reduces code verbosity. C++17's Standard Library also supports CTAD, so after upgrading your toolset, you can take advantage of this new feature when using STL types like std::pair and std::vector.
A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.
" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.
It's a conflict of type deduction. T
is deduced as int
from the first argument, and as const int
from the second argument. Hence type deduction fails (and the compiler presents a message which may or may not make the underlying cause clear).
If you want to make this function work without having to specify the template argument explicitly, you could make it so that only the second function argument drives the deduction:
template <class T>
struct NonDeduced { using type = T; }
template <class T>
T go(typename NonDeduced<T>::type a, T *b) { T *t; return *t; }
That way, T
will only be deducible from the second argument, and the first parameter will use the deduced T
without modification.
Because a
is declared to be passed by value, then in template argument deduction:
c) otherwise, if A is a cv-qualified type, the top-level cv-qualifiers are ignored for deduction:
That means, for go(x, &x);
, for the 1st argument x
, the template parameter T
will be deduced as int
, not const int
. For the 2nd argument T
will be deduced as const int
, because b
is declared to be passed by pointer (and the cv-qualifiers on the object being pointed are reserved; the same thing happens for pass-by-reference). Then deduction fails.
BTW: clang gives quite clear message for it:
prog.cc:4:3: note: candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'const int')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With