【发布时间】:2025-10-06 03:25:01
【问题描述】:
我可以用函数参数推断模板参数
template <typename T>
void f(T a)
{ /* */ }
f(4); // T inferred to be `int`
但是我不能使用函数参数来推断不是类型的模板参数:
template <int I>
void g(int I) // error: declaration of 'I' shadows template parameter
{ /* */ }
假设我想编写一个函数divive_dy_2(int number),并且我想确保number 不为零。
I've seen a very simple way to do this,这将要求我将参数传递给模板参数,然后如果它为 0,它将使用 SFINAE 禁用它。
但是在 API 中公开这样的内容感觉违反直觉。有什么解决办法吗?
(是的,我可以使用异常,什么不可以,甚至可能是一个更好的主意,但我现在正在学习 SFINAE,想知道它的限制在哪里)
【问题讨论】:
-
模板参数必须在编译时已知。直到运行时才知道参数的值(与其类型相反)。同样,SFINAE 在编译时工作。您不可能使用它来以某种方式作用于仅在运行时才知道的值。基本上,如果我有
int x; cin >> x; g(x);,那么如果用户将来输入0,您希望这段代码现在神奇地无法编译,但如果她输入1,则编译成功。 -
However I can't use function parameters to infer template parameters, which aren't types:。好吧,你可以; for example -
您可以将
std::integral_constant作为参数并使用用户定义的文字来使调用更好。不过,此时您也可以使用模板参数。 -
在您的第一个示例中,
T是从函数参数的类型推断出来的,而不是从它的值推断出来的。你不能使用函数参数的值来推断任何东西。