Подтвердить что ты не робот

Typedef для окружающего типа в С++

Есть ли способ построить typedef внутри объявления типа для объявленного (окружающего) типа без указания имени типа?

Пример:

class X
{
  public:
    typedef <fill in magic here> MyType;
  //...
};

Фон: Это кажется глупым при первом взгляде. Мне нужно это, потому что я создаю компиляцию-время-отражение моих классов данных с помощью макросов. Таким образом, в объявление класса данных вставлен макрос, который должен иметь дело с типом, в который он вставлен. До сих пор я нашел рабочие решения для MSVC и g++, которые оба полагаются на то, что я считаю недостатками в реализации. Поэтому они могут не работать в более новой версии. Clang не "съедает" ни одно из этих решений.

Мое текущее решение для MSVC определяет метод, а затем принимает его адрес только по его имени и вызывает небольшой помощник, который "возвращает" тип этого класса. (Clang и g++ ожидают полного имени метода, включая его имя класса).

Мое текущее решение для g++ определяет статический метод с возвращаемым типом std::remove_reference(decltype(*this)). (Clang и MSVC не разрешают this в статическом контексте).

Я бы предпочел стандартное решение, но специальное решение для clang тоже было бы в порядке.

Если ничего не работает, мне нужно передать имя класса макросу, но я стараюсь избегать этого, так как у меня уже есть много кода с использованием макроса.

EDIT: добавление образца того, как работает отражение (что может уточнить, что мне нужно):

class X : public Y
{
  public:
    //.. constructor and such stuff...

    int a;
    double b;
    std::string c;

    CLASSHEAD(Y)
      FIELD(a)
      FIELD(b)
      FIELD(c)
    CLASSFOOT
};

CLASSHEAD - макрос, который должен определять typedef. Это макрос VAR_ARGS, где аргументы получают базовые классы. Как сказано: Можно дать ему имя класса в качестве первого аргумента (в результате в CLASSHEAD(X, Y)). Но я почти не могу себе представить, что нет решения такой "простой" задачи, как типизировать окружающий тип...

4b9b3361

Ответ 1

Неттинг работает, поэтому использование класса Name в макросе является единственным рабочим решением

Ответ 2

Это точно не соответствует вашей спецификации, но я думаю, что это довольно близко:

class X
{
//Stuff...

//Use Macros to add:
struct MyType;

//Use class closing macro to insert variable between class-ending brace and semicolon      


} TYPE_VAR;
//Perhaps add random stuff to TYPE_VAR name to avoid collisions, like __FILE__
struct decltype(TYPE_VAR)::MyType
{
    typedef decltype(TYPE_VAR) V;
};

Затем выберите тип X, используя

X::MyType::V

Например, упрощенный CLASSFOOT может выглядеть следующим образом:

#define CLASSFOOT /*Your classfoot here*/ } TYPE_VAR; struct decltype(TYPE_VAR)::MyType {typedef decltype(TYPE_VAR) V;
//No }; at end on purpose- this will come from the class in which you placed CLASSFOOT

Насколько это достаточно для ваших целей?

Ответ 3

Поскольку вы уже используете макросы, вы можете использовать это решение fooobar.com/info/62901/...

#define CLASS_WITH_MY_TYPE(ClassName) \ 
    class ClassName                   \
    {                                 \
       using MyType = ClassName;

И затем используйте как

CLASS_WITH_MY_TYPE(X)
public:
  struct Y
  {
    using T = MyType;
  };
};

static_assert(std::is_same<X, typename X::Y::T>::value, "");

Отмечено как сообщество wiki, так как @Chris упомянул ссылку и оригинальный ответ был отправлен @Bartek Banachewicz