请帮我理解这个“包扩展不包含任何未扩展的参数包”编译器错误

Posted

技术标签:

【中文标题】请帮我理解这个“包扩展不包含任何未扩展的参数包”编译器错误【英文标题】:Please, help me understand this "pack expansion does not contain any unexpanded parameter packs" compiler error 【发布时间】:2021-06-18 18:59:58 【问题描述】:
template<typename ...>
bool foo(std::tuple<std::string,float> bar...)

    std::vector<std::tuple<std::string,float>> barList(bar...);

    // ...

这似乎不会产生任何语法错误。编辑器中该行没有错误指示器,但编译器停止

[bcc32c 错误] Foo.cpp(117):包扩展不包含任何未扩展的参数包

我尝试在线阅读,但我发现的所有示例要么似乎不完整,要么我不清楚。

一个简单的答案,为什么这不能编译将不胜感激。

【问题讨论】:

解释一下:“这不会产生任何语法错误,但是编译器[报告语法错误]” -- 咦?该错误语法错误。 @JaMiT Embarcadero 没有突出显示该行。 我不明白你在做什么。为什么typename... 参数未命名? 我同意你的编译器。您使用了没有要扩展的东西的包扩展。还有什么好说的?也许你可以解释一下你想要那条线的意思? (另外,请指出您的编译器指出语法错误的位置。谢天谢地,您将代码精简到一个几乎最小的示例,但作为副作用,编译器的“第 117 行”报告不再有意义。 ) @YanickRochon 那又怎样? Embarcadero 不是你的编译器吗?只有 C++ 编译器才是 C++ 语法错误构成的权威。语法荧光笔的编写速度很快,但会牺牲一些准确性。 【参考方案1】:

您的语法错误。您的功能等同于:

bool foo(int bar...)

    std::vector<int> barList(bar...);

    // ...

请注意,根本没有可变参数模板,也没有什么可解压的 - 相反,您创建了一个 C 风格的可变参数函数。

更改函数的最简单方法是:

template<typename... Args>
bool foo(Args... bar)

    std::vector<std::tuple<std::string,float>> barList(bar...);

    // ...

这并不理想,因为它使您的模板函数非常贪婪 - 它会很乐意使用任何参数,而不仅仅是字符串和浮点数的元组。

我们可以使用 C++20 concepts 来增加趣味性:

template<class T>
concept Tuple = std::is_same_v<T, std::tuple<std::string, float>>;

template<Tuple... T>
bool foo(T... bar)

    std::vector<std::tuple<std::string, float>> barList(bar...);

    // ...
    return true;

这允许这样使用:

foo(std::tuple<std::string, float>"ddd", 20, std::tuple<std::string, float>"ddd", 20);

但不是那样的:

foo(10, 20, nullptr);

【讨论】:

谢谢。第一个解决方案,使用template&lt;typename... Args&gt; 有效,但不是concept。这仍然是一个内部 API,所以无论如何它都不是什么大不了的 ATM。

以上是关于请帮我理解这个“包扩展不包含任何未扩展的参数包”编译器错误的主要内容,如果未能解决你的问题,请参考以下文章

请帮我处理这个查询(sql server 2008)

请帮我翻译这个 Python 代码 [重复]

npm install -g spray 然后出现受人尊敬的错误。请帮我解决这个问题

计算错误,请帮我看看?

请帮我解释一下这个函数(C语言)

请大家帮我翻译一段自我介绍