В:
for i in range(c/10):
В результате вы создаете число с плавающей точкой - чтобы исправить это, используйте оператор деления int:
for i in range(c // 10):
Другой способ основан на 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 с произвольным типом. Единственная цель введения имени члена - создать возможную двусмысленность при поиске имени члена - тип члена не важен.
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; }
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?
Почему бы вам просто не создать шаблонные специализации Check_x?
template<> bool Check_x(P1 p) { return true; }
template<> bool Check_x(P2 p) { return false; }
Черт возьми, если подумать. Если у вас всего два типа, зачем для этого вообще нужны шаблоны?
Являются ли функции (x, X, y, Y) абстрактным базовым классом, или их можно было бы так реорганизовать? В таком случае вы можете использовать макрос SUPERSUBCLASS () из Modern C ++ Design вместе с идеями из ответа на этот вопрос:
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 является идеальной заменой для работы с большинством концепций.