Reputation: 7009
Minimized example:
template <typename T, int N>
struct Deducer {
Deducer(int) {}
};
template <typename T, int N = 1>
void foo(Deducer<T, N> d){}
int main() {
foo<char>(345);
}
Yields error
candidate template ignored: could not match 'Deducer<char, N>' against 'int'
Why compiler ignores implicit cast?
If any simple workaround possible here?
I can think about two options:
(1) Specify all template parameters (not an option for me, real case have many of them, I want deduction) (2) Write intermediate function like this:
template <typename T, int N = 1>
void foo_step(int d){ foo<T, N>(d); }
Not an option either, I have large number of arguments.
Any ideas?
Upvotes: 1
Views: 79
Reputation: 218323
N
is deducible in
template <typename T, int N = 1> void foo(Deducer<T, N> d)
So default value = 1
is mostly useless.
If you want to force to call the method like:
foo<char>(345);
foo<char, 42>(345);
You might do:
// in C++20, std::type_identity might be used instead:
template <typename T> struct non_deducible { using type = T; };
template <typename T> using non_deducible_t = typename non_deducible<T>::type;
template <typename T, int N = 1> void foo(non_deducible_t<Deducer<T, N>> d);
But you no longer can do:
foo(Deducer<char, 42>());
Upvotes: 3
Reputation: 1529
As per this:
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.
You can try having something like this:
template <typename T, typename U, int N = 1>
void foo(U&& u)
{
foo(Deducer<T,N>(std::forward<U>(u)));
}
Upvotes: 2