C++/CLI 中的函数模板

Function templates in C++/CLI

我正在尝试在 C++/CLI 的命名空间中编写一些函数模板,如下所示:

// header file
namespace MyCLI {
    namespace MyFunctions {
        template <typename T>
        double sum(T a, T b) {
            return (double) a + b;
        }
    }
}

第一个问题是,当我将项目编译成一个 dll 并尝试使用它时,命名空间 MyFunctions 没有出现。我认为这是因为我没有为我需要的所有类型显式实例化我的模板,所以我在头文件的底部添加以下内容:

extern template double MyCLI::MyFunctions::sum<double>(double,double);

但这仍然无法让我访问 double 类型的函数 sum。我怀疑,由于项目被编译成托管代码,这遵循了 C# 的规则,即没有 class 就不能拥有函数。所以接下来我尝试在命名空间 MyCLI 中创建一个 class 并使 sum 成为 class 的静态成员,如下所示:

// header file
namespace MyCLI {

    public ref class MyFunctions
    {
    public:
        template <typename T>
        static double sum(T a, T b) {
            return (double) a + b;
        }
    };
}

extern template double MyCLI::MyFunctions::sum<double>(double,double); 

现在,当我使用程序集时,我可以在 MyCLI 中看到 MyFunctions class,但我仍然无法从 class 中访问 sum 函数.

如果有人能给我任何关于如何解决这个问题的建议,或者为什么我一开始就遇到这个问题,我将不胜感激。

这不是显式实例化模板的正确语法。您需要删除 extern 关键字并将实例化放在 cpp 文件中(而不是 header 中),因此它只定义一次。您无法看到该方法,因为它不存在 由于缺少模板实例化。模板不是泛型,它们看起来很相似但有很大不同。模板在编译时实例化,而泛型在运行时具体化

但是,如果您计划从不同的 .NET 语言使用此代码,那您就倒霉了:该方法的名称字面上包含尖括号,因此您如果不违反语言的命名规则,你将很难使用它。您可以使用反射,但我确定这不是您想要的。

对于这种简单的情况,您可以简单地编写几个重载(根本不使用模板),这是最简单的事情。如果您想要更多花哨的东西,请参阅 my answer here 获取灵感。