含可变参数的constexpr乘积函数编译失败:未展开参数包报错原因咨询
为什么版本2的constexpr乘积函数会报未展开参数包的错误?
我来帮你理清楚这个问题的核心原因——本质是返回值类型的要求和模板参数包的使用规则不匹配导致的。
先看能正常工作的版本1:
template <typename data_type, typename ...data_types> constexpr data_type Product1(data_type _first, data_types ..._rest) // 此代码可正常编译 :) { return _first*(_rest * ...); }
这里的返回值类型data_type是一个单独的模板参数(不是参数包),它对应函数第一个参数的类型,是明确的单一类型。编译器完全清楚这个返回值是什么,所以不会有问题,折叠表达式(_rest * ...)也能正确展开剩余参数进行计算。
再看版本2的问题所在:
template <typename ...data_type> constexpr data_type Product2(data_type ..._rest) // 此代码无法编译 :( { return (_rest * ...); }
这里你把data_type声明成了模板参数包(typename ...data_type),但函数的返回值位置要求的是一个单一的、确定的类型,而不是一堆类型组成的参数包。编译器根本不知道你要从data_type这个参数包里选哪个类型作为返回值——是第一个参数的类型?还是所有参数运算后的公共类型?它没有办法自动做出这个选择,所以就抛出了“Declaration type contains unexpanded parameter pack 'data_type'”的错误,意思就是:你用了一个没展开的参数包作为返回值类型,这不符合语法规则。
怎么修复版本2?
最简单的方式是让编译器自动推导返回值类型,把返回值改成auto:
template <typename ...data_types> constexpr auto Product2(data_types ..._rest) { return (_rest * ...); }
这样编译器会根据折叠表达式(_rest * ...)的计算结果,自动推导出合适的单一返回类型,代码就能正常编译运行了。
如果你想显式指定返回值类型(比如用参数包中第一个参数的类型),也可以用C++17的std::tuple_element或者自定义类型提取逻辑,但auto的方式显然更简洁直观。
内容的提问来源于stack exchange,提问作者niran90
相关产品推荐
相关产品推荐

