использование шаблонов для проверки, что переменная-член не работает на int - PullRequest
0 голосов
/ 02 августа 2011

Мне нужно проверить и посмотреть, есть ли у данного типа переменная-член. Однако когда задан тип, который не является классом или структурой, я получаю ошибку компилятора.

struct Vector {
    int x;
};

template <typename Type>
class has_member_x
{
   class yes { char m;};
   class no { yes m[2];};

   struct BaseMixin
   {
     int x;
   };

   struct Base : public Type, public BaseMixin {};

   template <typename T, T t>  class Helper{};

   template <typename U>
   static no deduce(U*, Helper<void (BaseMixin::*)(), &U::x>* = 0);
   static yes deduce(...);

public:
   static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));

}; 

int main() {

    BOOST_STATIC_ASSERT(has_member_x<int>::result);
    BOOST_STATIC_ASSERT(has_member_x<Vector>::result);
}

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

ошибка: базовый тип "int" не может быть структурой или типом класса

Есть ли способ сделать это в c ++ или c ++ 0x?

Ответы [ 2 ]

1 голос
/ 02 августа 2011

После исправления ошибки в исходном классе has_member_x и добавления специализации для типов class, как было предложено другими, окончательная рабочая версия выглядит следующим образом:

#include <type_traits>

template <typename Type, bool Enabled = std::is_class<Type>::value>
class has_member_x
{
public:
   static const bool result = false;
}; 

template <typename Type>
class has_member_x<Type, true>
{
   class yes { char m;};
   class no { yes m[2];};

   struct BaseMixin
   {
     int x;
   };

   struct Base : public Type, public BaseMixin {};

   template <typename T, T t>  class Helper{};

   template <typename U>
   static no deduce(U*, Helper<int BaseMixin::*, &U::x>* = 0);
   static yes deduce(...);

public:
   static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));
}; 
1 голос
/ 02 августа 2011

Для этого вы можете использовать boost :: enable_if и boost :: type_traits, в частности boost :: is_integral или boost :: is_class.

Попробуйте это (я не проверял, но это должно дать вам идею.):

struct Vector {
    int x;
};

template <typename Type, typename Enabled = void>
class has_member_x
{
public:
   static const bool result = false;
}; 

template <typename Type, typename Enabled = boost::enable_if<boost::is_class<Type> >::type > 
class has_member_x
{
   class yes { char m;};
   class no { yes m[2];};

   struct BaseMixin
   {
     int x;
   };

   struct Base : public Type, public BaseMixin {};

   template <typename T, T t>  class Helper{};

   template <typename U>
   static no deduce(U*, Helper<void (BaseMixin::*)(), &U::x>* = 0);
   static yes deduce(...);

public:
   static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));

}; 

int main() {

    BOOST_STATIC_ASSERT(has_member_x<int>::result);
    BOOST_STATIC_ASSERT(has_member_x<Vector>::result);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...