MSVC C++模板展开问题

template<typename... args>
void Func(args... arg){
std::listvoid*>> a_;
(a_.emplace_back(
    new args(std::move(arg))
)...);
}

这段代码为啥在MSVC下编译,提示“内部编译错误”

img

问题找到了
是因为对于参数arg的展开(而不是模板参数),必须需要运算符的连接
于是,我把代码改成:

template<typename... args>
void Func(args... arg){
std::list<std::shared_ptr<void*>> a_;
(a_.emplace_back(
    new args(std::move(arg))
)
, //添加逗号运算符
...);
}

问题圆满解决。。。
关键时候还得看我自己。。。

ChatGPT尝试为您解答,仅供参考
在 MSVC 中,可能会出现 "内部编译错误" 的原因是你的代码有语法错误或者类型错误,导致编译器无法继续编译。


具体来看,这段代码中,你在定义 Func 函数时使用了变长模板参数,并且在函数体内使用了 C++17 的参数指针扩展 (parameter pack expansion) 来将参数按照顺序插入 std::list 容器中。在这里,你的 a_.emplace_back 表达式会被展开为多个表达式,每个表达式中都会创建一个新的 args 类型的对象,并将 arg 参数传递给构造函数。


但是,这里有几个问题:

  • 你在定义 args 类型时没有提供任何具体的类型,这意味着 args 类型并不存在。
  • 你在定义 a_ 变量时使用了 std::shared_ptr<void*> 类型,但是这个类型没有默认构造函数,也就是说,无法使用 emplace_back 在尾部插入新的元素。
  • 你在创建新的 args 类型的对象时使用了 std::move 调用,但是 args 类型并不存在,所以无法调用 std::move。

因此,为了解决这些问题,你需要修改你的代码,使用有效的类型来代替 args,并且确保你的表达式语法正确。


例如,你可以使用如下的代码来修改你的函数:

template <typename T, typename... Args>
void Func(T arg, Args... args)
{
    std::list<std::shared_ptr<T>> a_;
    a_.emplace_back(std::make_shared<T>(std::move(arg)));
    (a_.emplace_back(std::make_shared<T>(std::move(args)))...);
}

这样,你就可以使用有效的类型来替换 args,并且使用 std::make_shared 函数来创建新的元素,这样就可以避免出现 "内部编译错误" 了。


此外,你还需要注意在使用参数指针扩展时,需要保证表达式的正确性,例如,你的表达式中不能出现语法错误或者类型错误。

模板展开一般用递归调用, 并须设置结束条件.