带有可变参数模板的constexpr

问题描述 投票:0回答:1

我有一个用于查找最小值的自定义函数:

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

我有两个问题:

  1. 为什么编译器需要一个
    minimumval(int&)
    ,因为它永远不会达到由
    if
    块保护的所述场景?
  2. constexpr 在这里有何不同?
c++ c++17
1个回答
0
投票
  1. 为什么编译器需要一个minimumval(int&),因为它永远不会达到由 if 块保护的所述场景?

与以下场景相同:

void existing_function();
void foo()
{
    if (true)
    {
        existing_function();
    }
    else
    {
        non_existing_function();
    }
}

non_existing_function
无论您是否到达分行,都必须申报。编译器必须生成代码来调用它。

  1. constexpr 在这里有何不同?

由于 constexpr if 在编译时求值,因此该语言表示未执行的分支将被丢弃。它仍然需要是有效的语法。因此,如果您有必须声明的非模板函数。但是,如果您有一个模板,那么该模板不会被实例化,这就是它在您的情况下编译的原因:

minimumval
是一个模板。

© www.soinside.com 2019 - 2024. All rights reserved.