我有一个用于查找最小值的自定义函数:
template<typename T, typename... Ts>
T minimumval(const T& a, const T& b, const Ts&... t) {
const auto m = a < b ? a : b;
if constexpr(sizeof...(t) > 0) {
return minimumval(m, t...);
}
return m;
}
这很完美。然而,当我移除
constexpr
的那一刻,它就窒息了:
<source>:14:26: error: no matching function for call to 'minimumval(const int&)'
14 | return minimumval(m, t...);
| ~~~~~~~~~~^~~~~~~~~
<source>:11:3: note: candidate: 'template<class T, class ... Ts> T minimumval(const T&, const T&, const Ts& ...)'
11 | T minimumval(const T& a, const T& b, const Ts&... t) {
| ^~~~~~~~~~
然后我需要用基本案例覆盖该函数才能使其正常工作。
template<typename T>
T minimumval(const T& val) {
return val;
}
template<typename T, typename... Ts>
T minimumval(const T& a, const T& b, const Ts&... t) {
const auto m = a < b ? a : b;
if (sizeof...(t) > 0) {
return minimumval(m, t...);
}
return m;
}
我有两个问题:
minimumval(int&)
,因为它永远不会达到由if
块保护的所述场景?为什么编译器需要一个minimumval(int&),因为它永远不会达到由 if 块保护的所述场景?
与以下场景相同:
void existing_function();
void foo()
{
if (true)
{
existing_function();
}
else
{
non_existing_function();
}
}
non_existing_function
无论您是否到达分行,都必须申报。编译器必须生成代码来调用它。
constexpr 在这里有何不同?
由于 constexpr if 在编译时求值,因此该语言表示未执行的分支将被丢弃。它仍然需要是有效的语法。因此,如果您有必须声明的非模板函数。但是,如果您有一个模板,那么该模板不会被实例化,这就是它在您的情况下编译的原因:
minimumval
是一个模板。