一般在其顶层获取结构体自己的类型

Jas*_*n C 5 c++ types

有没有一种方法可以struct在 said 声明的顶层一般获取 a 的类型struct而不引用其struct本身的实际名称?

例如:

#include <type_traits>

struct example {
    using attempt1 = example; // <- obvious, but not what I want
    using attempt2 = decltype(*this); // <- error
    using attempt3 = std::remove_pointer<decltype(this)>::type; // <- error
};
Run Code Online (Sandbox Code Playgroud)

或者:

#include <type_traits>

struct { // anonymous
    //using attempt1 = ...;
    using attempt2 = decltype(*this);
    using attempt3 = std::remove_pointer<decltype(this)>::type;
} x;
Run Code Online (Sandbox Code Playgroud)

这些程序当然无法在 GCC 9.x 和 10.x 上的 C++17 和 C++2a 模式下编译(“在顶层无效使用‘this’”),但我想做类似的事情attempt2或者attempt3我可以在struct不引用其名称的情况下获取 的类型(example第一种情况为“”)。

这可能吗?

我仔细看了看<type_traits>,但什么也没有出现在我的眼前,我想不出还能看哪里。

Hol*_*Cat 0

朋友注射来救援!

Run on gcc.godbolt.org

namespace impl
{
    namespace
    {
        template <typename T>
        struct tag { using type = T; };

        template <int L>
        struct adl_tag
        {
            friend constexpr auto adl_func(adl_tag<L>);
        };

        template <int L, typename T>
        struct adl_writer
        {
            friend constexpr auto adl_func(adl_tag<L>) {return tag<T>{};}
        };

        void adl_func() = delete;

        template <int L>
        struct adl_reader
        {
            using type = typename decltype(adl_func(adl_tag<L>{}))::type;
        };
    }
};

#define KNOWS_SELF_TYPE \
    [[maybe_unused]] void self_type_helper_dummy() \
    { \
        (void)::impl::adl_writer<__LINE__, std::remove_cvref_t<decltype(*this)>>{}; \
    } \
    [[maybe_unused]] static auto self_type_helper() \
    { \
        return ::impl::adl_reader<__LINE__>{}; \
    }

#define SELF_TYPE decltype(self_type_helper())::type
Run Code Online (Sandbox Code Playgroud)

进而...

#include <iostream>
#include <typeinfo>

struct A
{
    KNOWS_SELF_TYPE

    static void foo()
    {
        std::cout << typeid(SELF_TYPE).name() << '\n';
    }
};

int main()
{
    A::foo(); // Prints `1A` (mangled `A`).
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这个解决方案仅适用于静态(和非静态)成员函数。例如,它不允许您typedef在类范围内创建 self 类型。但我认为这可能已经足够好了。

此外,它在模板类中不起作用,因为self_type_helper_dummy由于未使用而未被实例化。这可以通过使其虚拟化来解决,但代价是使类具有多态性。