constexpr 对参数包的影响

affect of constexpr on Parameter pack

为什么没有constexpr这个代码无效:

template<typename ...Tpack>
auto CalculateSum(Tpack ...pack)
{
    if constexpr (sizeof...(Tpack) > 0)
    return (pack + ...);
    else
        return 0;
}

int main()
{
    std::cout << CalculateSum(2, 3, 4, 5, 7.5, 6) << '\n';
}

而如果参数中只有 int,它就有效。

编译器说:return 中的 'auto' 类型在此处推导为 'int' 但在较早的 return 语句

中推导为 'double'

但是constexpr如何解析呢?

你需要 if constexpr 而不是普通的 if 的原因是你试图 return 两种不同的类型,这是自动 return 不允许的类型推导。

对于 return (pack + ...);,return 类型将是 double,因为您的参数之一是 double。另一方面,return 0; 将变为 return 和 int。由于这些类型不匹配,您会收到错误消息。您需要 if constexpr 才能使 return (pack + ...);return 0; 成为实际编译的唯一代码行,这使您只有一个函数可以 return 的类型.

如果切换到使用尾随 return 类型,则可以去掉 if constexpr 并使用像

这样的普通 if
template<typename ...Tpack>
auto CalculateSum(Tpack ...pack) -> decltype((pack + ...))
{
    if (sizeof...(Tpack) > 0)
        return (pack + ...);
    else
        return {};
}

但这不是 DRY 并且打字更多,所以我更喜欢 if constexpr 版本。