Как обнаружить, существует ли определенная членская переменная в классе?

В:

for i in range(c/10):

В результате вы создаете число с плавающей точкой - чтобы исправить это, используйте оператор деления int:

for i in range(c // 10):
62
задан Kirill V. Lyadvinsky 29 July 2016 в 05:41
поделиться

6 ответов

Другой способ основан на SFINAE и для выражений . Если поиск имени приводит к неоднозначности, компилятор отклоняет шаблон

template<typename T> struct HasX { 
    struct Fallback { int x; }; // introduce member name "x"
    struct Derived : T, Fallback { };

    template<typename C, C> struct ChT; 

    template<typename C> static char (&f(ChT<int Fallback::*, &C::x>*))[1]; 
    template<typename C> static char (&f(...))[2]; 

    static bool const value = sizeof(f<Derived>(0)) == 2;
}; 

struct A { int x; };
struct B { int X; };

int main() { 
    std::cout << HasX<A>::value << std::endl; // 1
    std::cout << HasX<B>::value << std::endl; // 0
}

Он основан на блестящей идее кого-то в usenet.

Примечание: HasX проверяет любые данные или член функции с именем x с произвольным типом. Единственная цель введения имени члена - создать возможную двусмысленность при поиске имени члена - тип члена не важен.

48
ответ дан 24 November 2019 в 16:35
поделиться

Why don't you use specialization like this:

struct P1 {int x; };
struct P2 {int X; };

template<class P> 
bool Check_x(P p) { return true; }

template<> 
bool Check_x<P2>(P2 p) { return false; }
2
ответ дан 24 November 2019 в 16:35
поделиться

The second answer (litb's) to this shows how to detect a member:

Is it possible to write a template to check for a function's existence?

1
ответ дан 24 November 2019 в 16:35
поделиться

Почему бы вам просто не создать шаблонные специализации Check_x?

template<> bool Check_x(P1 p) { return true; }
template<> bool Check_x(P2 p) { return false; }

Черт возьми, если подумать. Если у вас всего два типа, зачем для этого вообще нужны шаблоны?

1
ответ дан 24 November 2019 в 16:35
поделиться

Являются ли функции (x, X, y, Y) абстрактным базовым классом, или их можно было бы так реорганизовать? В таком случае вы можете использовать макрос SUPERSUBCLASS () из Modern C ++ Design вместе с идеями из ответа на этот вопрос:

Отправка на основе типов во время компиляции

1
ответ дан 24 November 2019 в 16:35
поделиться

Boost.ConceptTraits предоставляет между другими макросами для определения характеристик типа, например BOOST_TT_EXT_DEFINE_HAS_MEMBER (name) , который определяет характеристика типа в форме:

has_member_##name<T>

Это дает истину, если у T есть именованный тип члена. Однако обратите внимание, что при этом не будут обнаружены члены ссылочного типа.

В вашем случае будет достаточно добавить файл заголовка

BOOST_TT_EXT_DEFINE_HAS_MEMBER_TYPE(x)

и проверить следующее

BOOST_STATIC_ASSERT(has_member_x<P1>::value);

Используемая техника такая же, как и объясненная в некоторых из предыдущих ответов.

К сожалению, эта библиотека больше не поддерживается. Теперь, когда C ++ 0x не будет включать концепцию, эта библиотека вместе с SFINAE является идеальной заменой для работы с большинством концепций.

4
ответ дан 24 November 2019 в 16:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: