Why is the template argument deduction not working here?
Just as first note, typename name is used when you mention a dependent name. So you don't need it here.
template <class T>
struct S
{
typedef T& type;
};
Regarding the template instantiation, the problem is that typename S<A>::type
characterizes a nondeduced context for A. When a template parameter is used only in a nondeduced context (the case for A in your functions) it's not taken into consideration for template argument deduction. The details are at section 14.8.2.4 of the C++ Standard (2003).
To make your call work, you need to explicitly specify the type:
temp<char>(c);
automatic template argument deduction not working
Template argument deduction only applies to functions. In
general, the compiler won't have the necessary information to
deduce the arguments for a class. For this reason, it's common
in such cases to add a function along the lines of:
template <typename T>
index_cmp<T>
indexCmp( T const& arr )
{
return index_cmp<T>( arr );
}
You can then call:
sort( index_mu.begin(), index_mu.end(), indexCmp( mu_pt_corrected ) );
The compiler will deduce the type of the function, which in turn
defines the type.
Why does template argument deduction/substitution fail here?
Your function template takes three type arguments:
template <typename F,typename OUT,typename IN>
OUT memoization(IN in) { ... }
You're passing in test
for F
. test
isn't a type, it's a value. Also, the expression F(in)
in your function template is wrong for the same reason.
This approach in general is pretty flawed as it seems pretty backwards from what actually is going on. Namely, it's the function that's being memoized, not a value. Also requiring the function value at compile time is pretty limiting.
A better approach is to treat memoization as a decorator. That is:
template <class F>
Memoized<F> memoize(F f) {
return {f};
}
such that:
auto memo_test = memoize(test);
memo_test(0); // performs computation
memo_test(0); // doesn't perform computation
memo_test(0); // ditto
I leave the implementation of Memoized<T>
as an exercise.
Template argument deduction Doesn't Work for Function Template <unresolved overloaded function type>
SomeFunc(func<5,int>);
You pass a pointer to the function
func<5,int>
andT
becomesvoid(*)(int)
which is fine. It also works insideSomeFunc
when you use the function pointera
to call the function it is pointing at.SomeFunc(func<5>);
Deduction is not possible. The compiler is not able to look forward to see that inside
SomeFunc
you will calla(6)
so therefore it must instantiatefunc<5,int>
and makea
point at it.SomeFunc(func<5>(20));
Here you actually call
func<5,int>
(with the argument20
) and pass the return value from that call intoSomeFunc
. There is no return value fromfunc<5,int>
since it'svoid
andvoid a;
is not valid. If it had been valid, the next problem would have been that you try to calla
inSomeFunc
. The argument toSomeFunc
must be a callable of some sort or elsea(6);
will fail.
C++ template deduction is not working
Your function expects an argument of type std::function
, but you're passing it a pointer to function instead. &g<int>
is convertible to the std::function
parameter type, but template argument deduction requires exact matches (except for the adjustments allowed by [temp.deduct.call]/2,3,4), user defined conversions are not considered.
Writing f(std::function<void(int)>(g<int>))
will work because you're now passing an std::function
, so template argument deduction will succeed.
f<int>(&g<int>)
also works because you've now explicitly specified T
, it no longer participates in template argument deduction and user defined conversions will be attempted.
Class template argument deduction not working with alias template
This was a feature that we considered when formulating the proposal, but it was eventually cut from the C++17 feature set because we didn't yet have a good enough design for it. In particular, there are some subtleties regarding how you select and transform deduction guides from the aliased template into deduction guides for the alias template. There are also open questions as to how to behave if the alias template is not a simple alias for another template. Some examples:
template<typename T> struct Q { Q(T); }; // #1
template<typename T> struct Q<T*> { Q(T); }; // #2
template<typename U> using QP = Q<U*>;
int *x;
Q p = x; // deduces Q<int*> using #1, ill-formed
QP q = x; // deduces Q<int*> using #1, or
// deduces Q<int**> using #2?
template<typename T> Q(T) -> Q<T>; // #3
QP r = x; // can we use deduction guide #3 here?
template<typename T> Q(T*) -> Q<T**>; // #4
int **y;
QP s = y; // can we use deduction guide #4 here?
template<typename T> struct A { typedef T type; struct Y {}; };
template<typename T> using X = typename A<T>::type;
template<typename T> using Y = typename A<T>::Y;
X x = 4; // can this deduce T == int?
Y y = A<int>::Y(); // can this deduce T == int?
There are decent answers to the above questions, but tackling them adds complexity, and it seemed preferable to disallow deduction for alias templates for C++17 rather than rush something flawed in.
Update [C++20]: This topic was revisited for C++20, and we approved P1814R0, which permits class template argument deduction for alias templates.
The original example is now valid. For the examples above:
CTAD still only considers constructors from the primary template. So in
QP q = x;
, #2 is not considered, and instead #1's constructor is used. That constructor is implicitly converted into a guide forQ
:template<typename T> Q(T) -> Q<T>;
which is then converted into a guide for the alias template
QP
by deducing the right-hand side of the guide forQ
(Q<T>
) from the right-hand side of the alias template (Q<U*>
), which deducesT
=U*
, then substituting that back into the guide, thereby producing the equivalent of:template<typename U> Q(U*) -> Q<U*>;
// ... which is effectively ...
template<typename U> QP(U*) -> QP<U>;
// ... except that explicit deduction guides are not
// permitted for alias templatesThat guide is then used to deduce the type of
q
, which deducesU
=int
, so the type ofq
isQ<int*>
, so the initialization ofq
is ill-formed.The initialization of
r
does consider deduction guide #3, which is transformed into a guide forQP
as described aboveThe initialization of
s
does consider deduction guide #4; deducingQ<T**>
fromQ<U*>
deduces nothing, so we retain the deduction guidetemplate<typename T> Q(T*) -> Q<T**>;
as-is, but add a constraint that the result of deduction must match the form of
QP
. We then deduceT
=int
, substitute that in to compute a result type ofQ<int**>
, and check that we can deduceQP<U>
fromQ<int**>
, which we can. So the type ofs
is deduced asQ<int**>
.CTAD for alias templates is only supported where the right-hand side of the alias template is a simple-template-id (of the form
maybe::stuff::templatename<args>
). So neitherX
norY
is deducible.
Issue with template argument deduction
This will not work, since all the uses of T
(which are CopyOrConstRef_t<T>
) in the argument list of Lerp
are in non-deduced contexts:
The non-deduced contexts are:
The nested-name-specifier of a type that was specified using a qualified-id.
Here's an example from the reference:
Template parameters do not participate in template argument deduction if they are used only in non-deduced contexts. For example,
template<int i, typename T>
T deduce(typename A<T>::X x, // T is not deduced here
T t, // but T is deduced here
typename B<i>::Y y); // i is not deduced here
Your example is the same, except that there is no argument that can be deduced, and you have an alias template for the arguments (which doesn't change anything).
Related Topics
How to Convert a Double into a String in C++
C++ Redefinition Header Files (Winsock2.H)
Static Member Initialization in a Class Template
Compiling a C++ Program With Gcc
Why Do People Use _ (Double Underscore) So Much in C++
Can Inner Classes Access Private Variables
Creating a 3D Sphere in Opengl Using Visual C++
Create Registry Entry to Associate File Extension With Application in C++
Eclipse Cdt: Symbol 'Cout' Could Not Be Resolved
How Does This "Size of Array" Template Function Work
What's the Difference Between a Header File and a Library
How to Build Qt For Visual Studio 2010
How to Use Stringstream to Separate Comma Separated Strings
"Incomplete Type" in Class Which Has a Member of the Same Type of the Class Itself
Initializer_List and Template Type Deduction
Remove Comments from C/C++ Code