【问题标题】:Workaround for GCC 4.8.1: sorry, unimplemented: mangling argument_pack_selectGCC 4.8.1 的解决方法:抱歉,未实现:修改 argument_pack_select
【发布时间】:2014-03-07 08:08:24
【问题描述】:

考虑以下代码:

#include <tuple>

template <class Result, class Function, class... Types>
Result f(Function func, Types... values)
{
    return std::get<0>(std::make_tuple(func(values)...));
}

template <class... Types>
int g(const Types... values)
{
    return std::get<0>(std::make_tuple(f<Types>([](int n){return n;}, values)...));
}

int main()
{
    return g(42);
}

在 g++ 4.8.1 下,它产生:

mangling.cpp: In instantiation of ‘g(const Types ...) [with Types = int]::__lambda0’:
mangling.cpp:12:50:   required from ‘struct g(const Types ...) [with Types = int]::__lambda0’
mangling.cpp:12:77:   required from ‘int g(const Types ...) [with Types = int]’
mangling.cpp:17:16:   required from here
mangling.cpp:12:57: sorry, unimplemented: mangling argument_pack_select
     return std::get<0>(std::make_tuple(f<Types>([](int n){return n;}, values)...));
                                                         ^
mangling.cpp: In instantiation of ‘struct g(const Types ...) [with Types = int]::__lambda0’:
mangling.cpp:12:77:   required from ‘int g(const Types ...) [with Types = int]’
mangling.cpp:17:16:   required from here
mangling.cpp:12:57: sorry, unimplemented: mangling argument_pack_select
mangling.cpp:12:57: sorry, unimplemented: mangling argument_pack_select
mangling.cpp:4:8: error: ‘Result f(Function, Types ...) [with Result = int; Function = g(const Types ...) [with Types = {int}]::__lambda0; Types = {int}]’, declared using local type ‘g(const Types ...) [with Types = {int}]::__lambda0’, is used but never defined [-fpermissive]
 Result f(Function func, Types... values)

有没有办法避免这个问题?是否在 g++ 4.8.2 或 4.9.0 中报告和纠正过?

编辑:我刚刚在这里报告了这个错误:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60130

【问题讨论】:

  • 在 gcc 4.9 中提供 ICE。
  • Vincent:发布一个您正在尝试解决的实际问题的示例。 @DanielFrey 的回答是正确的:如果您只是想避开 ICE,您所要做的就是将 lambda 拉到包扩展之外。 (如果你需要它constexpr,解决方案是一样的。我可以发布代码,但在你真正告诉我们你所有的秘密要求之前,我不想分散丹尼尔的回答。)
  • @Quuxplusone 我正在处理一个严重依赖最糟糕/最优雅的元编程技巧的代码,我在这个例子中隔离了这个问题。但基本上,我需要做与提供的示例中导致问题的完全相同的事情(这不是 XY 问题)。
  • 然后接受丹尼尔的回答。 :) (翻译:是的,你正在处理一个 XY 问题,在你告诉我们 X 之前,我们唯一能做的就是为你解决 Y,这显然对你不是很有用。)

标签: gcc c++11 compiler-errors variadic-templates compiler-bug


【解决方案1】:

您是否需要为每个扩展参数创建一个新的 lambda?否则这会解决它:

template <class... Types>
int g(const Types... values)
{
    auto func = [](int n){return n;};
    return std::get<0>(std::make_tuple(f<Types>(func, values)...));
}

Live example

【讨论】:

  • @Vincent 不确定 C++1y 是否适合您以及它是否真的适用于 constexpr,但 maybe this 有帮助吗?
  • @Daniel 在 C++1y 中,您可以将 constexpr 添加到您在答案中编写的函数中!无论如何,在 C++11 中,您可以通过适当使用辅助函数来 constexprify 任何内容。即,您将g 实现为return ghelper([](int n){return n;}, values...);,其中ghelper 以显而易见的方式实现。
猜你喜欢
  • 1970-01-01
  • 2012-02-10
  • 2021-07-15
  • 1970-01-01
  • 1970-01-01
  • 2014-11-07
  • 2021-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多