在多个共享库的情况下,如何仅创建 class 模板静态成员的一个实例?
How to make one instance only of class template static member in case of several shared libraries?
我有一个带有静态成员的模板 class,为简单起见:
template<typename T>
struct A
{
static inline int x = 1;
};
但是如果我在几个 shared-libraries 中包含 header 和 struct A
定义,它们中的每一个都会有自己的 A<T>::x
实例。而且我希望仅在某个共享库和访问它的所有其他库中拥有 A<T>::x
的实例(对于某些固定的 T
类型列表)。
在Visual Studio中我可以在header
中写
#ifdef _WIN32
# ifdef MY_LIB_EXPORT
# define MY_LIB_API __declspec(dllexport)
# else
# define MY_LIB_API __declspec(dllimport)
# endif
#else
# define MY_LIB_API
#endif
template<typename T>
struct A
{
MY_LIB_API static int x;
};
并在来自所选动态库的 .cpp-file 中:
template<> int A<SpecificType1>::x = 0;
template<> int A<SpecificType2>::x = 0;
…
但不幸的是,这种方式不适用于 linux/clang,在其他 .cpp-files 中我得到:
error: instantiation of variable 'A<SpecificType1>::x' required here, but no definition is available
是否有解决我的任务的通用方法?
对于 GCC,您可以使用:
#define EXPORT __attribute__((visibility("default")))
我已经使用 CMake 使用以下设置对其进行了测试 mylib.h:
#define EXPORT __attribute__((visibility("default")))
template<typename T>
struct A
{
EXPORT static int x;
};
mylib.cpp
#include "mylib.h"
template<> int A<int>::x = 1;
template<> int A<bool>::x = false;
main.cpp
std::cout << "A<int>: " << A<int>::x << std::endl;
std::cout << "A<bool>: " << A<bool>::x << std::endl;
输出:
A<int>: 1
A<bool>: 0
CMakeLists.txt
# Change the default to hidden, then you need to explicitly set it
# Thus, normally, you shouldn't have the problem
add_compile_options(-fvisibility=hidden) # only for testing the EXPORT define
add_library(mylib SHARED mylib.cpp)
add_executable(example main.cpp main2.cpp) # Main2 also used mylib
target_link_libraries(example mylib)
因此,对于通用选项,我建议将此定义添加到您的 if else define 宏列表中。
我有一个带有静态成员的模板 class,为简单起见:
template<typename T>
struct A
{
static inline int x = 1;
};
但是如果我在几个 shared-libraries 中包含 header 和 struct A
定义,它们中的每一个都会有自己的 A<T>::x
实例。而且我希望仅在某个共享库和访问它的所有其他库中拥有 A<T>::x
的实例(对于某些固定的 T
类型列表)。
在Visual Studio中我可以在header
中写#ifdef _WIN32
# ifdef MY_LIB_EXPORT
# define MY_LIB_API __declspec(dllexport)
# else
# define MY_LIB_API __declspec(dllimport)
# endif
#else
# define MY_LIB_API
#endif
template<typename T>
struct A
{
MY_LIB_API static int x;
};
并在来自所选动态库的 .cpp-file 中:
template<> int A<SpecificType1>::x = 0;
template<> int A<SpecificType2>::x = 0;
…
但不幸的是,这种方式不适用于 linux/clang,在其他 .cpp-files 中我得到:
error: instantiation of variable 'A<SpecificType1>::x' required here, but no definition is available
是否有解决我的任务的通用方法?
对于 GCC,您可以使用:
#define EXPORT __attribute__((visibility("default")))
我已经使用 CMake 使用以下设置对其进行了测试 mylib.h:
#define EXPORT __attribute__((visibility("default")))
template<typename T>
struct A
{
EXPORT static int x;
};
mylib.cpp
#include "mylib.h"
template<> int A<int>::x = 1;
template<> int A<bool>::x = false;
main.cpp
std::cout << "A<int>: " << A<int>::x << std::endl;
std::cout << "A<bool>: " << A<bool>::x << std::endl;
输出:
A<int>: 1
A<bool>: 0
CMakeLists.txt
# Change the default to hidden, then you need to explicitly set it
# Thus, normally, you shouldn't have the problem
add_compile_options(-fvisibility=hidden) # only for testing the EXPORT define
add_library(mylib SHARED mylib.cpp)
add_executable(example main.cpp main2.cpp) # Main2 also used mylib
target_link_libraries(example mylib)
因此,对于通用选项,我建议将此定义添加到您的 if else define 宏列表中。