可变参数模板错误:“在实例化中”(gcc 9.2)
Posted
技术标签:
【中文标题】可变参数模板错误:“在实例化中”(gcc 9.2)【英文标题】:Variadic template error: 'In instantiation of' (gcc 9.2) 【发布时间】:2020-03-07 11:54:26 【问题描述】:我正在 Jason Turner 的 youtube channel 上学习 c++17 上的可变参数模板,然后我复制了他的示例代码(如下所示)。在他的视频中,他使用带有 gcc 7 的网站 godbolt.org。
#include <utility>
template<typename ... B>
struct Merged : B ...
template<typename ... T>
Merged(T&& ... t) : B(std::forward<T>(t))...
using B::operator()...;
;
template<typename ... T>
Merged(T...) -> Merged<std::decay_t<T>...>;
int main()
const auto l1 = []() return 4; ;
const auto l2 = [](const int i) return i * 10; ;
Merged merged(l1,
l2,
[](const double d) return d * 3.2; );
return 0;
我使用 gcc 9.2 在我的计算机上尝试了代码,但出现以下错误:
在 'Merged::Merged(T&& ...) 的实例化中(其中 T = const main()::&, const main()::&, main()::; B = ] ':
我尝试使用 Godbolt 站点检查它,但它也无法编译(使用 gcc 7.1 和 gcc 9.2)并给出更多错误,例如:
错误:在“合并”之前缺少模板参数合并合并(l1,
和
错误:在 ')' 标记之前的预期主表达式 [](const double d) return d * 3.2; );
这个错误意味着什么以及我需要做些什么来修复它?
在我的电脑中编译行:
g++ -Wall -fexceptions -O2 -pedantic -Wextra -Wall -std=c++1z -m64 -c /home/thearquitect/Desktop/C++/variadic.cpp -o ~/Desktop/obj/variadic.o
g++ -o ~/Desktop/bin/variadic ~/Desktop/obj/variadic.o -s -m64
godbolt try
【问题讨论】:
In instantiation of ...
不是完整的错误消息。 missing template arguments before 'merged'
表示您忘记了 -std=c++17
。添加缺少的标志后,我得到:gcc.godbolt.org/z/rXjgGp 出于某种原因,GCC 将B
推导出为一个空列表,而忽略了推导指南。相同的代码可以在 Clang 中运行,因此它看起来像是 GCC 错误。
@HolyBlackCat 很奇怪,因为我使用了这个标志......(我编辑了问题以显示它)
【参考方案1】:
这个错误意味着什么以及我需要做些什么来修复它?
据我了解,您的代码没有问题。
我怀疑是一个 g++ 错误。
修复它......好吧......绕过它......不要问我为什么,但我看到这对两个编译器都有效,需要第一个模板参数,在可变参数列表之前,用于@987654321 @。
我的意思是:以下struct
template <typename B0, typename ... B>
struct Merged : public B0, public B ...
template <typename T0, typename ... T>
Merged (T0 && t0, T && ... t)
: B0std::forward<T0>(t0), Bstd::forward<T>(t)...
using B0::operator();
using B::operator()...;
;
连同下面的扣分指南
template <typename T0, typename ... T>
Merged (T0, T ...)
-> Merged<std::decay_t<T0>, std::decay_t<T>...>;
适用于两种编译器。
您的原始演绎指南也适用于修改后的struct
。
-- 编辑--
我看到你也可以解决问题(用两个编译器编译)维护 struct
只用可变参数列表
template <typename ... B>
struct Merged: public B ...
template <typename ... T>
Merged (T && ... t)
: Bstd::forward<T>(t)...
using B::operator()...;
;
并使用带有必需参数的演绎指南
template <typename T0, typename ... T>
Merged (T0, T ...)
-> Merged<std::decay_t<T0>, std::decay_t<T>...>;
【讨论】:
这对我帮助很大!那么主要的问题是在 gcc 的演绎指南(DG)中。实际上,它需要两个 DG(而不是替代品),因为仅使用您的 DG 我无法仅使用一个参数来实例化 Merged。以上是关于可变参数模板错误:“在实例化中”(gcc 9.2)的主要内容,如果未能解决你的问题,请参考以下文章