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)。

有相关问题,但我还是不太明白是怎么回事,无法解决这个问题:

代码:

https://android.googlesource.com/device/generic/vulkan-cereal/+/refs/heads/master/stream-servers/vulkan/vk_fn_info.h

#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;                          \
    };

但这阻止了它在命名空间中的使用。需要两个单独的宏来满足命名空间内部和外部的使用。