c++ - GCC ICE——替代函数语法、可变参数模板和元组

标签 c++ gcc c++11

(与 C++0x, How do I expand a tuple into variadic template function arguments? 相关。)

以下代码(见下文)取自此 discussion .目标是将函数应用于元组。我简化了模板参数并修改了代码以允许返回泛型类型的值。

虽然原始代码编译正常,但当我尝试使用 GCC 4.4.3 编译修改后的代码时,

g++ -std=c++0x main.cc -o main

GCC 报告内部编译器错误 (ICE),并显示以下消息:

main.cc: In function ‘int main()’:
main.cc:53: internal compiler error: in tsubst_copy, at cp/pt.c:10077
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.4/README.Bugs> for instructions.

问题:代码是否正确?还是 ICE 是由非法代码触发的?

// file: main.cc
#include <tuple>

// Recursive case
template<unsigned int N>
struct Apply_aux
{
  template<typename F, typename T, typename... X>
  static auto apply(F f, const T& t, X... x)
    -> decltype(Apply_aux<N-1>::apply(f, t, std::get<N-1>(t), x...))
  {
    return Apply_aux<N-1>::apply(f, t, std::get<N-1>(t), x...);
  }
};

// Terminal case
template<>
struct Apply_aux<0>
{
  template<typename F, typename T, typename... X>
  static auto apply(F f, const T&, X... x) -> decltype(f(x...))
  {
    return f(x...);
  }
};

// Actual apply function
template<typename F, typename T>
auto apply(F f, const T& t)
  -> decltype(Apply_aux<std::tuple_size<T>::value>::apply(f, t))
{
  return Apply_aux<std::tuple_size<T>::value>::apply(f, t);
}

// Testing
#include <string>
#include <iostream>

int f(int p1, double p2, std::string p3)
{
  std::cout << "int=" << p1 << ", double=" << p2 << ", string=" << p3 << std::endl;
  return 1;
}

int g(int p1, std::string p2)
{
  std::cout << "int=" << p1 << ", string=" << p2 << std::endl;
  return 2;
}

int main()
{
  std::tuple<int, double, char const*> tup(1, 2.0, "xxx");
  std::cout << apply(f, tup) << std::endl;
  std::cout << apply(g, std::make_tuple(4, "yyy")) << std::endl;
}

备注:如果我在递归情况下对返回类型进行硬编码(参见代码),那么一切都很好。也就是说,将此代码段替换为递归情况不会触发 ICE:

// Recursive case (hardcoded return type)
template<unsigned int N>
struct Apply_aux
{
  template<typename F, typename T, typename... X>
  static int apply(F f, const T& t, X... x)
  {
    return Apply_aux<N-1>::apply(f, t, std::get<N-1>(t), x...);
  }
};

唉,这是对原始问题的不完整解决方案。

最佳答案

我试过你在 g++4.6 上编写代码。由于缺少实现,它无法编译。但是,实现通用性的一种方法是将独立函数包装在 std::function 包装器中,并使用 result_type typedef,如下所示。

template<typename F, typename T>
typename F::result_type apply(F f, const T& t)
{
  ...
}
int f(int p1, double p2, std::string p3) 
{
  std::cout << "int=" << p1 << ", double=" << p2 << ", string=" << p3 << std::endl;
  return 1;
}
int main()
{
  std::tuple<int, double, char const*> tup(1, 2.0, "xxx");
  std::function<int (int, double, char const *)> func = &f; 
  std::cout << apply(func, tup) << std::endl;

}

关于c++ - GCC ICE——替代函数语法、可变参数模板和元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2828014/

相关文章:

c - 函数内的函数

c++ - 如何将 wince sdk 6 添加到嵌入式 Visual C++ 4?

c++ - "struct type variablename"作为声明有效吗?

c - 为什么语法错误会导致无限循环而不是编译时的 fatal error ?

c - 时间测量因微 Controller 而异

c++ - 具有静态绑定(bind)成员函数指针的可变参数模板的多个特化?

c++ - Lambda 成员函数

c++ - 使用 std::min 或三元运算符的性能差异?

c# - 将 C# 应用程序转换为 C++ 枚举

c++ - 从数组复制字节时出现运行时错误