将函数模板转换为函数重载集

Convert function template to function overload set

本文关键字:重载 函数 函数模板 转换      更新时间:2023-10-16

假设这是我的库。这是一个非常庞大的库:

图书馆.hpp

template<class usertype> void function_name(usertype aaa)
{
}

这是我的主要

int main()
{
    int x=3;
    function_name(x);
    double y=3.5;
    function_name(y);
    return 0;
}

我不知道图书馆里发生了什么。我想要的是转换库以适应我的代码。实际上,将模板还原为实际代码。

我需要将上面的库代码转换为:

void function_name(int aaa)
{
}
void function_name(double aaa)
{
}

因此,我可以根据自己的需要操作库,而不是操作适用于所有人的通用代码。如何完成从模板到真实代码的转换(无需手动操作,而是以自动方式)?

编辑:

我想将整个文件library.hpp转换为不包含模板的library_2.hpp。而是有两个实际实现的功能。这是在编译过程中发生的情况。

不是想减少编译时间。我正在处理一个由 196 个文件组成的庞大库。在库中的众多函数中,我需要其中一些与我的工作相关。我打算破解和扩展这个库。扩展整个库对我来说是巨大的工作量。我只想扩展我需要的东西。因此,对我来说,减少代码并简化它并删除所有用显式代码替换它们的模板非常重要。 我不擅长C++,它编译器错误。因此,在如此庞大的库中,我更喜欢使用自动方法,而不是涉及手动代码操作。我也不擅长理解这个图书馆。要理解该库,最好将其复杂的函数转换为与我真正需要的内容相关的显式实现代码。然后我可以更好地理解别人的代码。我将删除与我的需求无关的功能。我也不关心图书馆的更新。一旦我建立了新的图书馆,维护它就是我的职责。新库将更小,更易于维护。评论显示,有些人从不同的角度看待我的目标。我希望这个解释是清楚的。

出于好奇,我将要操作的库是与数学计算相关的,里面很少有变化或错误。

我不

完全确定您想要实现什么,但通过阅读评论,我认为您主要关心的是您正在尝试减少编译时间并减少与模板相关的错误消息。 您不是在尝试将库函数专门化为自己的类型。

如果您只使用少数类型实例化库中的模板化函数,则有一个简单的方法可以将模板从图片中取出。 但它会迫使你为你想要使用它的模板化函数和类型的每个组合编写两行代码。

创建您自己的头文件library_wrapper.hpp . 在那里,您声明要使用的函数的非模板版本。

library_wrapper.hpp

#ifndef LIBRARY_WRAPPER_H
#define LIBRARY_WRAPPER_H
#include <vector>  // just an example
namespace library_wrapper
{
  void
  function_name(int);
  void
  function_name(double);
  int
  another_function(const std::vector<double>&, bool);
}
#endif

然后使用您鲜为人知的模板库一劳永逸地"实现"它们。

library_wrapper.cpp

#include "library_wrapper.hpp"
#include <library.hpp>  // the template library
namespace library_wrapper
{
  void
  function_name(const int arg1)
  {
    return library::function_name(arg1);
  }
  void
  function_name(const double arg1)
  {
    return library::function_name(arg1);
  }
  int
  another_function(const std::vector<double>& arg1, const bool arg2)
  {
    return library::function(arg1, arg2);
  }
}

你编译library_wrapper.cpp一次,对抗模板,然后继续只使用提供非模板化函数的包装器。

请注意,这种方法危及模板如此快速的主要原因之一:内联。 包装函数不能在编译时内联,因为您对编译器隐藏了它们的定义。 这是故意的,另一方面,可以缩短编译时间。 链接时内联可能会给你一些内联,但你不应该认为这是理所当然的。

请注意,此解决方案不适用于类型(与函数相反)。 你可以尝试写一些pimpl包装器,但我不推荐这个。 也许最好的办法是与您的模板库成为朋友......

针对更新后问题的更新

我正在处理一个由 196 个文件组成的庞大库。在库中的众多函数中,我需要其中一些与我的工作相关。

出于好奇,我将要操作的库是与数学计算相关的,里面很少有变化或错误。

这似乎上述方法确实有所帮助。

扩展整个库对我来说是巨大的工作量。我只想扩展我需要的东西。因此,对我来说,减少代码并简化它并删除所有用显式代码替换它们的模板非常重要。

我不认为这是一个好方法。 相反,将库用作黑匣子,并在其上构建自己的库。 将开发人员的精力集中在新功能上,并从基础库的更新中受益。

我假设有问题的库是自由软件(否则,你想做的事情无论如何都是非法的),自由软件项目应该相互支持。 如果你正在库 X 之上构建一个很棒的库 Y,两者项目,X和Y,可以受益。 另一方面,如果您只删除其他库的一部分并添加其他功能,那么您的两个竞争项目最终都可能不完整且不兼容,这对您和您的用户来说都是令人沮丧的。

要理解该库,最好将其复杂的函数转换为与我真正需要的内容相关的显式实现代码。然后我可以更好地理解别人的代码。

我不认为你可以合理地期望一些机器生成的代码会比库的原始人类编写的代码更具可读性。 毕竟,人类程序员被教导为人类编写代码,但编译器针对其他方面进行了优化。

我不擅长C++,它编译器错误。[...]我也不擅长理解这个图书馆。

我打算破解和扩展这个库。

我也不关心图书馆的更新。一旦我建立了新的图书馆,维护它就是我的职责。

我不想显得粗鲁,但是...你看到问题了吗?

专业分类

template<>
void function_name(int aaa)
{
}
template<>
void function_name(double aaa)
{
}

示例代码

#include <iostream>
template<class usertype>
void function_name(usertype aaa)
{
    std::cout << "defaultn";
}
template<>
void function_name(int aaa)
{
    std::cout << "int value = " << aaa << 'n';
}
template<>
void function_name(double aaa)
{
    std::cout << "double value = " << aaa << 'n';
}
int main()
{
    int x = 3;
    function_name(x);
    double y = 3.5;
    function_name(y);
    struct Z{} z;
    function_name(z);
    return 0;
}