为什么模板参数推导失败?

Why template argument deduction fails?

本文关键字:失败 参数 为什么      更新时间:2023-10-16

最小化示例:

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);
}

神博尔特示例

产量误差

candidate template ignored: could not match 'Deducer<char, N>' against 'int'

为什么编译器忽略隐式强制转换?

如果这里有任何简单的解决方法?

我可以考虑两个选项:

(1(指定所有模板参数(对我来说不是选项,实际案例有很多,我要扣除( (2(像这样编写中间函数:

template <typename T, int N = 1>
void foo_step(int d){ foo<T, N>(d); }

也不是一个选择,我有很多论点。

有什么想法吗?

N可推导

template <typename T, int N = 1> void foo(Deducer<T, N> d)

因此,默认值= 1大多是无用的。

如果要强制调用该方法,例如:

foo<char>(345);
foo<char, 42>(345);

您可能会执行以下操作:

// 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);

但是你再也做不到了:

foo(Deducer<char, 42>());

根据这个:

类型

推断不考虑隐式转换(上面列出的类型调整除外(:这是重载解决的工作,稍后会发生。

你可以尝试这样的东西:

template <typename T, typename U, int N = 1>
void foo(U&& u)
{
foo(Deducer<T,N>(std::forward<U>(u)));
}