2014-01-21 2 views
0

Я знаю, что на C++ нет отражения, как в Java, C# и AS3. Но мне действительно нужно знать, какой тип члена имеет класс. (Я полагаю, что пользователь создает класс таким образом, который я могу ему предоставить, а затем я должен иметь возможность перечислять все типы участников.) Как я могу это сделать?C++ как узнать, какой тип элемента имеет класс в C++

Конечно, я могу добавить фазу предварительной обработки на естественную предварительную обработку, чтобы выполнить это, но я хочу другое решение. Более элегантный и не хаки.

Пример:

Пользователь создает класс, как это: (способ создания класса мы можем по-другому, например, я могу требовать наследство от какого-либо класса или с помощью макроса ...)

class A 
{ 
    int a; 
    double b; 
}; 

И теперь я могу получить список всех членов класса A {"int", "double"} как список строк. как это, например:

GetTypes::listOfMemberTypes(A) or GetTypes<A>::listOfMemberTypes 

списка.Возвраты, который содержит «Int», «двойной»

+2

Можете ли вы привести пример того, что вы хотите сделать? –

+1

Итак, ваш вопрос: «Я знаю, что это невозможно в рамках языка, и я знаю, что могу сделать это за пределами языка, но как я могу это сделать в пределах языка? Действительно? Программирование не работает на основе« довольно пожалуйста, «C++ не будет спонтанно выражать функцию отражения только потому, что вам« действительно нужно ». – jalf

+0

jalt такие лозунги просто популярны и ничего больше. Есть ли способ определить, является ли это объектом или перечислением? is, и это не язык, встроенный, см. boost :: is_enum – Narek

ответ

6

Читает исходный код для данного класса.

+0

+1. Один из способов сделать это - использовать существующий компилятор; Clang предоставляет [LibClang] (http://clang.llvm.org/docs/Tooling.html) для таких целей. – Angew

+0

jalf, для юмора 100 из 100, что касается технического ответа 0.;) – Narek

+0

По крайней мере, у меня есть предложение по этой теме: http://www.open-std.org/jtc1/sc22/wg21/docs/papers /2014/n3883.html –

0

В C++ нет хорошего способа сделать это, как вы сказали. Однако, если вы готовы пойти на решения, которые не являются межплатформенными, для этого может быть возможно использовать отладочные символы. Например, если приложение скомпилировано GCC с помощью «-g» (или вы можете получить копию двоичного файла, скомпилированного с этой опцией), вы можете проверить символы отладки, которые были скомпилированы в двоичный файл. Для этого я хотел бы взглянуть на исходный код GDB.

+0

Никаких отладочных символов, определенно, не является решением, которое я ищу. – Narek

0

Возможно, требуется, чтобы A был std::tuple, поэтому у вас есть тип типа в компиляторе.

Затем вы можете создать функцию для создания списка имен (с typeid(T).name()).

Что-то вроде:

namespace detail { 

template <typename T> struct tuple_name; 

template <typename ... Ts> 
struct tuple_name<std::tuple<Ts...>> 
{ 
    static constexpr std::array<std::string, sizeof...(Ts)> get_names() 
    { 
     return { typeid(Ts).name()... }; 
    } 
}; 

} // namespace detail 

template <typename T> 
static constexpr auto get_names() 
-> decltype(detail::tuple_name<T>::get_names()) 
{ 
    return detail::tuple_name<T>::get_names(); 
} 

Так проверить:

class C{}; 

typedef std::tuple<int, char, C> UserType; 

int main(int argc, char *argv[]) 
{ 
    for (const auto& name : get_names<UserType>()) 
     std::cout << name << std::endl; 

    return 0; 
} 
+0

Как это можно сделать? Пожалуйста, будьте более конкретными (пример?). – Narek

+0

@ Нарек: Добавлен образец. – Jarod42

+0

В этом коде у вас нет пользовательского класса, у вас есть пользовательский экземпляр структуры данных. – Narek

Смежные вопросы