how to solve: error: global qualification of class name is invalid before '{' token
how to solve: error: global qualification of class name is invalid before '{' token
我正在尝试构建 https://android.googlesource.com/device/generic/vulkan-cereal
但是 运行 出现了一个似乎只发生在 GCC 上的错误(我必须使用 v8.3)。
有相关问题,但我还是不太明白是怎么回事,无法解决这个问题:
- Global qualification in base specifier
- Global qualification in a class declarations class-head
代码:
#define REGISTER_VK_FN_INFO(coreName, allNames) \
struct coreName; \
template <> \
struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> { \
static constexpr auto names = std::make_tuple allNames; \
using type = PFN_vk##coreName; \
};
REGISTER_VK_FN_INFO(GetPhysicalDeviceProperties2,
("vkGetPhysicalDeviceProperties2KHR", "vkGetPhysicalDeviceProperties2"))
错误:
vulkan-cereal/stream-servers/vulkan/vk_fn_info.h:31:57: error: global qualification of class name is invalid before '{' token
struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> { \
^
/vulkan-cereal/stream-servers/vulkan/vk_fn_info.h:36:1: note: in expansion of macro 'REGISTER_VK_FN_INFO'
REGISTER_VK_FN_INFO(GetPhysicalDeviceProperties2,
^~~~~~~~~~~~~~~~~~~
我该怎么做才能构建它?
全局限定符是前面的两个冒号:
struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {
^^
但答案是删除所有限定符:
struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {
^^^^^^^^^^^^^^^^^^^^^^^
所以变成:
#define REGISTER_VK_FN_INFO(coreName, allNames) \
struct coreName; \
template <> \
struct GetVkFnInfo<coreName> { \
static constexpr auto names = std::make_tuple allNames; \
using type = PFN_vk##coreName; \
};
诀窍在于,这揭示了 knock-on 由于在另一个文件的命名空间之外不正确使用宏而导致的错误:
vk_util_unittest.cpp:28:25: error: expected constructor, destructor, or type conversion before '(' token
REGISTER_VK_FN_INFO_TEST(GfxstreamTestFunc, ("vkGfxstreamTestFunc", "vkGfxstreamTestFuncGOOGLE",
最后的更改需要修复 vk_util_unittest.cpp 中的命名空间,以便它们与 vk_fn_info.h
中的命名空间相匹配
作为替代方案,我发现宏可以在命名空间外使用,只要它是完全限定的(不包括无效的全局限定):
#define REGISTER_VK_FN_INFO_EXTERN(coreName, allNames) \
struct coreName; \
template <> \
struct vk_util::vk_fn_info::GetVkFnInfo<coreName> { \
static constexpr auto names = std::make_tuple allNames; \
using type = PFN_vk##coreName; \
};
但这阻止了它在命名空间中的使用。需要两个单独的宏来满足命名空间内部和外部的使用。
我正在尝试构建 https://android.googlesource.com/device/generic/vulkan-cereal 但是 运行 出现了一个似乎只发生在 GCC 上的错误(我必须使用 v8.3)。
有相关问题,但我还是不太明白是怎么回事,无法解决这个问题:
- Global qualification in base specifier
- Global qualification in a class declarations class-head
代码:
#define REGISTER_VK_FN_INFO(coreName, allNames) \
struct coreName; \
template <> \
struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> { \
static constexpr auto names = std::make_tuple allNames; \
using type = PFN_vk##coreName; \
};
REGISTER_VK_FN_INFO(GetPhysicalDeviceProperties2,
("vkGetPhysicalDeviceProperties2KHR", "vkGetPhysicalDeviceProperties2"))
错误:
vulkan-cereal/stream-servers/vulkan/vk_fn_info.h:31:57: error: global qualification of class name is invalid before '{' token
struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> { \
^
/vulkan-cereal/stream-servers/vulkan/vk_fn_info.h:36:1: note: in expansion of macro 'REGISTER_VK_FN_INFO'
REGISTER_VK_FN_INFO(GetPhysicalDeviceProperties2,
^~~~~~~~~~~~~~~~~~~
我该怎么做才能构建它?
全局限定符是前面的两个冒号:
struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {
^^
但答案是删除所有限定符:
struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {
^^^^^^^^^^^^^^^^^^^^^^^
所以变成:
#define REGISTER_VK_FN_INFO(coreName, allNames) \
struct coreName; \
template <> \
struct GetVkFnInfo<coreName> { \
static constexpr auto names = std::make_tuple allNames; \
using type = PFN_vk##coreName; \
};
诀窍在于,这揭示了 knock-on 由于在另一个文件的命名空间之外不正确使用宏而导致的错误:
vk_util_unittest.cpp:28:25: error: expected constructor, destructor, or type conversion before '(' token
REGISTER_VK_FN_INFO_TEST(GfxstreamTestFunc, ("vkGfxstreamTestFunc", "vkGfxstreamTestFuncGOOGLE",
最后的更改需要修复 vk_util_unittest.cpp 中的命名空间,以便它们与 vk_fn_info.h
中的命名空间相匹配作为替代方案,我发现宏可以在命名空间外使用,只要它是完全限定的(不包括无效的全局限定):
#define REGISTER_VK_FN_INFO_EXTERN(coreName, allNames) \
struct coreName; \
template <> \
struct vk_util::vk_fn_info::GetVkFnInfo<coreName> { \
static constexpr auto names = std::make_tuple allNames; \
using type = PFN_vk##coreName; \
};
但这阻止了它在命名空间中的使用。需要两个单独的宏来满足命名空间内部和外部的使用。