【问题标题】:C++ Template preprocessor toolC++ 模板预处理器工具
【发布时间】:2010-11-11 12:09:12
【问题描述】:

是否有编译器或独立的预处理器接收 C++ 文件并运行模板扩展传递,生成具有扩展模板实例化的新 C++ 代码?

我记得在 90 年代中期这样一个工具还是新的和实验性的模板,而预处理器是一种在没有原生模板支持的情况下使用编译器进行模板编程的方法。

这比宏处理步骤复杂得多,因为它可能需要解析和标记代码才能理解上下文。

我希望在编写 OpenCL 代码时使用这样的工具。 OpenCL 是 C++,但不支持模板。我希望我可以编写模板,甚至是简单的模板,例如仅带有整数或布尔参数的模板,并且有一些工具预解析文件并通过查找模板的使用并扩展调用并给我新的 C++ 代码OpenCL 编译器可以理解。

即使是一个非常有限的工具也可能有用,它不需要支持每个模板怪癖,甚至也不需要支持多个模块或任何东西。

替代方案:#define 无处不在的宏……更丑陋、不安全、效率更低、通用性更低。

【问题讨论】:

  • OpenCL 的语言基于 C99 语法,而不是根据您链接的页面的 C++。
  • AMD对openCL做了一些扩展,如果你只针对AMD设备,你可以开发模板代码。我们不能使用模板来开发我们的算法是一个痛苦。

标签: c++ templates macros opencl c-preprocessor


【解决方案1】:

Comeau C++ 可以将 C++“编译”为 C。这似乎接近您的目标,因为 OpenCL 不支持 C++——它更接近于 C。

【讨论】:

  • 是的!这是我 15 年前出于同样原因使用的工具!太好了,谢谢。
  • “出于同样的原因”——你在 15 年前就有了 OpenCL?哇! ;-)
  • 现在这个网站不工作了,据我了解,Comeau C++ 现在没有开发,不是吗?
【解决方案2】:

没有这样的工具 - 模板是语言的一部分,而不是一些预处理程序 - 它们由编译器处理,就像其他代码一样。

【讨论】:

  • 是的.. 这样的工具确实需要解析 C++。这就是它比宏预处理器更复杂的原因。
  • 好吧,就像我说的,据我所知,不存在这样的事情。我看不出它如何处理模板并保持“非模板”代码不变。
  • @Neil:最初的 c++ 编译器只是将 c++ 代码转换为有效的 c,然后使用 c 编译器对其进行编译。当然现在不再是这种情况了,但过去相当普遍。
  • @Evan 我知道 - 从 E 版本开始,我就是 cfront 的用户。然而,最初的问题说他想扩展模板,但不理会其他 C++ 代码,生成一个新的 C++ 程序,这是 cfront(和 comeau)无法做到的。现在事实证明他想要一些不同的东西——这就是生活。
  • @Evan Teran:最初的 C++ 编译器并没有像我们所知的那样编译 C++。他们编译了 C++ 的第一个版本,这是非常不同的。 ;)
【解决方案3】:

C++ Insights (https://cppinsights.io/) 能够做到这一点(以及更普遍地扩展“高级”语法糖 C++ 结构。它基于 Clang,因此它对代码的理解与可能,并支持最新标准。

它将例如扩展

extern "C" void printf(...);
template<typename T>
int foo(T t)
{
  if constexpr(sizeof(T) == 4) {
    printf("int: %d", t);
  }
  else {
    printf("something else: %d", (int)t);
  }
}

int main()
{
    const char arr[10]{2,4,6,8};

    for(const char& c : arr)
    {
      foo(c);
    }
}

进入

extern "C" void printf(...);
template<typename T>
int foo(T t)
{
  if constexpr(sizeof(T) == 4) {
    printf("int: %d", t);
  }
  else {
    printf("something else: %d", (int)t);
  }
}

/* First instantiated from: insights.cpp:19 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
int foo<char>(char t)
{
  if constexpr(false) {
  } else /* constexpr */ {
    printf("something else: %d", static_cast<int>(t));
  } 
  
}
#endif


int main()
{
  const char arr[10] = {2, 4, 6, 8, '\0', '\0', '\0', '\0', '\0', '\0'};
  {
    char const (&__range1)[10] = arr;
    const char * __begin1 = __range1;
    const char * __end1 = __range1 + 10L;
    for(; __begin1 != __end1; ++__begin1) {
      const char & c = *__begin1;
      foo(c);
    }
    
  }
  return 0;
}

【讨论】:

    猜你喜欢
    • 2016-06-30
    • 2011-04-26
    • 2011-10-20
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 2012-06-25
    • 1970-01-01
    相关资源
    最近更新 更多