【问题标题】:Generically obtaining a struct's own type at its top level在顶层一般获取结构自己的类型
【发布时间】:2021-04-08 10:48:23
【问题描述】:

有没有办法在顶级的struct声明中通用获取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
};

或者:

#include <type_traits>

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

这些程序当然无法在 GCC 9.x 和 10.x 上的 C++17 和 C++2a 模式下编译(“在顶层无效使用 'this'”),但我想执行attempt2attempt3 之类的操作,我可以在不提及其名称的情况下获取struct 的类型(在第一种情况下为“example”)。

这可能吗?

我浏览了&lt;type_traits&gt;,但什么都没有出现,我想不出还有哪里可以看。

【问题讨论】:

标签: c++ types


【解决方案1】:

朋友注射救援!

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

然后……

#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`).
}

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 2016-09-14
    • 2013-03-20
    相关资源
    最近更新 更多