C++ 为什么共享_ptr类型的前向声明会破坏gcc610中其他模板类型显式实例化的可见性?
在我的macbook上,使用macports gcc610,使用-fvisibility=hidden,我看到一种奇怪的行为 我有一个使用模板的库。为了防止用户实例化这些模板,我将模板定义移动到了一个单独的文件中。我想显式地实例化这个模板中唯一可以存在的实例 此外,这些显式实例化需要从共享对象导出 只有在GCC中,我才发现一个奇怪的include-order依赖关系,它似乎决定了显式实例化是否实际从共享库导出。这是我的图书馆: A.h 财产.hC++ 为什么共享_ptr类型的前向声明会破坏gcc610中其他模板类型显式实例化的可见性?,c++,templates,gcc,llvm,visibility,C++,Templates,Gcc,Llvm,Visibility,在我的macbook上,使用macports gcc610,使用-fvisibility=hidden,我看到一种奇怪的行为 我有一个使用模板的库。为了防止用户实例化这些模板,我将模板定义移动到了一个单独的文件中。我想显式地实例化这个模板中唯一可以存在的实例 此外,这些显式实例化需要从共享对象导出 只有在GCC中,我才发现一个奇怪的include-order依赖关系,它似乎决定了显式实例化是否实际从共享库导出。这是我的图书馆: A.h 财产.h #ifndef __Property__ #def
#ifndef __Property__
#define __Property__
namespace commons
{
template<typename T>
class __attribute__ ((visibility ("default"))) Property
{
private:
T member;
public:
void set(const T & t);
const T & get() const;
};
}
#endif // __Property__
在转发声明周围添加一个#pragma GCC visibility push(默认值)
,似乎是可行的,但在我看来,具有显式可见性的a.h头的后续包含无论如何都应该覆盖转发声明
有人能给我解释一下这种区别吗?谢谢
#ifndef __Property__
#define __Property__
namespace commons
{
template<typename T>
class __attribute__ ((visibility ("default"))) Property
{
private:
T member;
public:
void set(const T & t);
const T & get() const;
};
}
#endif // __Property__
#include <memory>
#include "Property.h"
// #include "A.h" // adding this lets the Property instance be exported
namespace commons
{
struct A;
struct OhNoes
{
std::shared_ptr<A> bad; // removing this also lets the Property instance be exported
};
}
#include "A.h"
//
// boring implementation for template class
//
namespace commons
{
template<typename T> const T & Property<T>::get() const{return member;}
template<typename T> void Property<T>::set(const T & t){member = t;}
}
//
// important explicit instantiation
// this type should be DSO visible because Property and A are both visible
//
template class commons::Property<std::shared_ptr<commons::A>>;
cpp_fiddle $ /opt/local/bin/g++-mp-6 @flags.h -dynamiclib -o g.so Property.cpp
cpp_fiddle $ nm g.so | c++filt
0000000000000d74 unsigned short commons::Property<std::__1::shared_ptr<commons::A> >::set(std::__1::shared_ptr<commons::A> const&)
0000000000000e84 unsigned short commons::Property<std::__1::shared_ptr<commons::A> >::get() const
0000000000000e92 T std::__1::shared_ptr<commons::A>::~shared_ptr()
0000000000000ef6 short std::__1::(anonymous namespace)::ignore
U std::__1::__shared_weak_count::__add_shared()
U std::__1::__shared_weak_count::__release_shared()
0000000000000ef5 short std::__1::allocator_arg
0000000000000ef4 short std::__1::piecewise_construct
U dyld_stub_binder
cpp_fiddle $ /opt/local/bin/clang++-mp-4.0 -std=c++14 -fvisibility=hidden -dynamiclib -o c.so Property.cpp
cpp_fiddle $ nm c.so | c++filt
0000000000000da0 T commons::Property<std::__1::shared_ptr<commons::A> >::set(std::__1::shared_ptr<commons::A> const&)
0000000000000f20 T commons::Property<std::__1::shared_ptr<commons::A> >::get() const
0000000000000f30 unsigned short std::__1::shared_ptr<commons::A>::~shared_ptr()
0000000000000f50 unsigned short std::__1::shared_ptr<commons::A>::~shared_ptr()
U std::__1::__shared_weak_count::__add_shared()
U std::__1::__shared_weak_count::__release_shared()
U dyld_stub_binder
-std=c++14
-fvisibility=hidden
-nostdinc++
-nodefaultlibs
-isystem "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1"
-isysroot "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
-lc
-lc++
-lc++abi
-lgcc_s.10.5
-lgcc_eh