C++ 静态模板函数可以在具有 C 链接的结构中吗?

Posted

技术标签:

【中文标题】C++ 静态模板函数可以在具有 C 链接的结构中吗?【英文标题】:Can a C++ static template function be in a struct with C linkage? 【发布时间】:2015-05-05 22:31:26 【问题描述】:

我的头文件中有以下声明:

extern "C" 
    struct lfModifier 
        template<typename T>
        static void ModifyColor_Vignetting_PA (
           void *data, float x, float y, T *rgb, int comp_role, int count);
    

GCC 可能正确地抱怨“错误:带有 C 链接的模板”。但模板毕竟是静态的。我可以很容易地将它从课堂上移到 cpp 文件中。我不喜欢这样做,因为将它放在结构中会增加代码的可读性。

有没有办法在这种情况下使用静态模板?

【问题讨论】:

即使这样也没有实际用处 你想通过具有 C 链接的 member 函数来完成什么?没有其他类的extern C 成员函数可以共享相同的名称? @Mondkin:它是关于 C++ 库的。我认为(我维护其他人的代码)目标是为 C 和 C++ 程序使用相同的库头文件。 C 程序可以看到struct 和属性,而 C++ 程序可以看到除了 C 链接之外的所有内容。好吧,然后,模板成员失败了。 你不能在头文件中包含这个,因为 C 不知道模板是什么。如果你使用 #define 将它隐藏在 C 中,你就打破了单一定义规则。 @BenVoigt:它对 C 隐藏,#ifdef __cplusplus 【参考方案1】:

如果你需要结构中的其他成员有C链接,模板函数可以有C++链接。

extern "C" 
    struct lfModifier 
        int val;
        void foo();

        extern "C++" template<typename T>
        static void ModifyColor_Vignetting_PA (
           void *data, float x, float y, T *rgb, int comp_role, int count);
    


结构成员的extern C++ 将覆盖结构的extern C 属性。

【讨论】:

【参考方案2】:
// Inside header
extern "C"  struct X; ;
struct X 
    template <typename T> static void f() 
;

// Inside cpp
int main() 
    X::f<int>();

【讨论】:

此代码块可能会回答问题,请尝试添加相关说明。【参考方案3】:

我认为这是不可能的。

检查这个其他问题及其答案: In C++ source, what is the effect of extern "C"?

最重要的部分:

类成员忽略外部“C” 至多一个具有特定名称的函数可以具有“C”链接(无论命名空间如何) 'extern "C"' 中的'static' 有效;如此声明的实体具有内部链接,因此没有语言链接

最重要的是中间的那个:当你实例化你的模板时,你会有两个同名但参数不同的函数,这是 C 不直接支持的。所以 C++ 编译器需要修改名称用于模板化函数。

另外,当你在结构之外声明你的函数并且你说它是static 你给它内部链接,所以extern C 将被忽略(这就是它在这种情况下编译的原因)。您是否使用objdump 查看编译后的名称以确保它没有被破坏?

【讨论】:

以上是关于C++ 静态模板函数可以在具有 C 链接的结构中吗?的主要内容,如果未能解决你的问题,请参考以下文章

C++创建一个结构体应该放在.cpp文件中吗?然后调用的时候只要包含这个.cpp文件?

仅具有静态方法的模板类使用 .cpp 文件实现给出错误

c++调用c函数,如果它确实存在

C++模板,静态函数特化

C- 声明为静态的函数的链接

C++使用模板类调用非静态成员函数