具有隐藏可见性的 C++ 模板参数问题

Posted

技术标签:

【中文标题】具有隐藏可见性的 C++ 模板参数问题【英文标题】:Issue with C++ template arguments with hidden visibility 【发布时间】:2011-07-19 20:08:05 【问题描述】:

我在 gcc 下使用 -fvisibility=hidden 编译以下代码:

template<class T> struct /*__attribute__ ((visibility("default")))*/ A ;

template<class T> struct B

    B() __attribute__ ((visibility("default")));
;

template<class T> B<T>::B() 

template class B<int>;
template class B<A<int> >;

如果我通过 nm | 运行生成的目标文件grep B,我明白了

000000000002b97c t B<A<int> >::B()
000000000002b972 t B<A<int> >::B()
000000000002b968 T B<int>::B()
000000000002b95e T B<int>::B()

即,B&lt;int&gt; 是可见的,但 B&lt;A&lt;int&gt; &gt; 是不可见的。如果我取消注释 sn-p 标记 A&lt;T&gt; 为可见,B&lt;A&lt;int&gt; &gt; 变为可见。但是,我不想将所有 A 标记为可见,因为在实际代码中 A&lt;T&gt; 包含大量应该保持私有的方法。

为什么A&lt;T&gt; 的可见性会影响B&lt;A&lt;T&gt; &gt; 的可见性?我可以让B&lt;A&lt;T&gt; &gt; 可见而不使所有A&lt;T&gt; 可见吗?

【问题讨论】:

【参考方案1】:

假设我正确理解了 ODR(我可能不理解 :)),隐藏您的 B&lt;A&lt;int&gt; &gt; 实例化看起来像是与 ODR 相关的要求。如果B&lt;A&lt;int&gt; &gt; 未隐藏,则A&lt;&gt; 的成员的多个实例可能存在并被引用,从而导致ODR 违规。 GCC 的symbol visibility Wiki 简要描述了在具有模糊链接(包括模板)的“实体”上使用隐藏符号可见性时的此类违规行为(参见例外部分)。

您想通过隐藏A&lt;&gt; 模板中的符号来达到什么目的?

【讨论】:

在我的代码中 A 是一个带有大量内联方法的向量类,为了文件大小和加载时间,我想避免将它们全部导出。【参考方案2】:

如果您特别希望隐藏 A 的内联方法,请尝试使用 -fvisibility-inlines-hidden

【讨论】:

我用的是-fvisibility=hidden,所以-fvisibility-inlines-hidden是多余的。 似乎是这样,但 GCC 指南建议添加它:In your build system (Makefile etc), you will probably wish to add the -fvisibility=hidden and -fvisibility-inlines-hidden options to the command line arguments of every GCC invocationgcc.gnu.org/wiki/Visibility

以上是关于具有隐藏可见性的 C++ 模板参数问题的主要内容,如果未能解决你的问题,请参考以下文章

具有 ListView 可见性的 SimpleCursorAdapter

为啥 PHP 的空合并运算符 (??) 不能处理具有不同可见性的类常量?

警告:XXXX 在 YYYY 中具有不同的可见性(默认)和在 ZZZZ 中(隐藏)

更改了其中一个侦听器适合可见性的 JPanel

C# 窗口可见性,折叠和隐藏

阻止可见性的测试用例