Ответ 1
Неттинг работает, поэтому использование класса Name в макросе является единственным рабочим решением
Есть ли способ построить 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)
). Но я почти не могу себе представить, что нет решения такой "простой" задачи, как типизировать окружающий тип...
Неттинг работает, поэтому использование класса Name в макросе является единственным рабочим решением
Это точно не соответствует вашей спецификации, но я думаю, что это довольно близко:
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
Насколько это достаточно для ваших целей?
Поскольку вы уже используете макросы, вы можете использовать это решение 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