Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么共享_ptr类型的前向声明会破坏gcc610中其他模板类型显式实例化的可见性?_C++_Templates_Gcc_Llvm_Visibility - Fatal编程技术网

C++ 为什么共享_ptr类型的前向声明会破坏gcc610中其他模板类型显式实例化的可见性?

C++ 为什么共享_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

在我的macbook上,使用macports gcc610,使用-fvisibility=hidden,我看到一种奇怪的行为

我有一个使用模板的库。为了防止用户实例化这些模板,我将模板定义移动到了一个单独的文件中。我想显式地实例化这个模板中唯一可以存在的实例

此外,这些显式实例化需要从共享对象导出

只有在GCC中,我才发现一个奇怪的include-order依赖关系,它似乎决定了显式实例化是否实际从共享库导出。这是我的图书馆:

A.h

财产.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__
在转发声明周围添加一个
#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