#include <iostream>
#include <utility>
template<std::size_t... items>
constexpr std::size_t count()
{
return std::index_sequence<items...>().size();
}
template<std::size_t... items>
constexpr std::size_t fold_mul()
{
if( count<items...>() == 0 )
{
return 1;
}
else
{
return (... * items);
}
}
int main()
{
std::cout << "Result: " << fold_mul<>() << "\n";
}
此代码应输出 1
,但会引发错误:<source>:19:28: error: fold of empty expansion over operator*
19 | return (... * items);
我的问题是: 为什么这不起作用,因为 fold_expression 显然在
else
部分。作为引用,此实现有效:
template<typename... Args>
constexpr std::size_t fold_mul();
template<std::size_t... j>
requires (count<j...>() > 0)
constexpr std::size_t fold_mul()
{
return (j * ...);
}
template<>
constexpr std::size_t fold_mul()
{
return 1;
}
最佳答案
问题是,当指定折叠表达式为空扩展时,(... * items)
在编译时无效;即使它不会在运行时被评估。
您可以使用 constexpr if (C++17 起);那么当被指定为空扩展的折叠表达式时,else 部分将被丢弃。
If the value is true, then statement-false is discarded (if present), otherwise, statement-true is discarded.
template<std::size_t... items>
constexpr std::size_t count()
{
return std::index_sequence<items...>().size();
}
template<std::size_t... items>
constexpr std::size_t fold_mul()
{
if constexpr ( count<items...>() == 0 )
// ^^^^^^^^^
{
return 1;
}
else
{
return (... * items);
}
}
关于c++ - 带有空参数包的一元折叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66132666/