Кто хотел определения наличия функции-члена?
Fw: An omnipotant swap?
#include <list>
namespace omni{
template <class T, T val>
struct member_wrapper{};
template <class T>
char test_for_swap(const T&, member_wrapper<void (T::*)(T&), &T::swap>* p = 0);
template <class T>
double test_for_swap(const T&, ...);
template <class T>
struct has_member_swap
{
static T t;
static const bool value = (1 == sizeof(test_for_swap(t)));
};
//BOOST_STATIC_ASSERT(has_member_swap<std::list<int>::value);
//BOOST_STATIC_ASSERT(!has_member_swap<int>::value);
//BOOST_STATIC_ASSERT(!has_member_swap<noswap>::value);
template<bool b>
struct swapper
{
template <class T>
static void swap(T& t1, T& t2)
{ std::swap(t1, t2); }
};
template<>
struct swapper<true>
{
template <class T>
static void swap(T& t1, T& t2)
{ t1.swap(t2); }
};
template <class T>
void swap(T& t1, T& t2)
{
swapper<has_member_swap<T>::value>::swap(t1, t2);
}
} // namespace omni
struct noswap{};
int main()
{
std::list<intl1, l2;
omni::swap(l1, l2);
noswap s1, s2;
omni::swap(s1, s2);
int i1, i2;
omni::swap(i1, i2);
return 0;
}
Используется фича компиляторов
"Substitution Failure Is Not An Error" (SFINAE), на основе которой в boost'e сейчас разрабатывается инструмент
enable_if.
Re: Кто хотел определения наличия функции-члена?
|
От: |
Аноним
|
|
Дата: | 14.09.03 10:09 |
|
Оценка: |
|
Здравствуйте, MaximE, Вы писали:
<...>
Нельзя ли заставить это работать на VC6 ?
Re[2]: Кто хотел определения наличия функции-члена?
|
От: |
MaximE
|
|
Дата: | 14.09.03 11:02 |
|
Оценка: |
|
Здравствуйте, <Аноним>, Вы писали:
А>Нельзя ли заставить это работать на VC6 ?
Пока никто не смог.
Re: Кто хотел определения наличия функции-члена?
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Кто хотел определения наличия функции-члена?
Душа обязана трудиться! (с) Н.Заболоцкий.
Re[3]: Кто хотел определения наличия функции-члена?
|
От: |
MaximE
|
|
Дата: | 16.09.03 07:33 |
|
Оценка: |
|
Здравствуйте, _Obelisk_, Вы писали:
_O_>Ага, только непонятно, ЗАЧЕМ это нужно ??
Вот как раз одно применение найдено — ссылка в начале на omnipotent swap.
Re: Кто хотел определения наличия функции-члена?
Здравствуйте, MaximE, Вы писали:
ME>ME>
ME>namespace omni{
ME>template <class T, T val>
ME>struct member_wrapper{};
ME>template <class T>
ME>char test_for_swap(const T&, member_wrapper<void (T::*)(T&), &T::swap>* p = 0);
ME>template <class T>
ME>double test_for_swap(const T&, ...);
ME>}
ME>
Прикольно.
Обидно, что сам до этого додуматься не смог.
Re: Кто хотел определения наличия функции-члена?
|
От: |
Кодт
|
|
Дата: | 18.09.03 09:21 |
|
Оценка: |
|
Здравствуйте, MaximE, Вы писали:
<>
ME>Используется фича компиляторов "Substitution Failure Is Not An Error" (SFINAE), на основе которой в boost'e сейчас разрабатывается инструмент enable_if.
Я фигею, дорогая редакция.
Какой замысел, оооо!
Перекуём баги на фичи!
Re: Кто хотел определения наличия функции-члена?
|
От: |
gid_vvp
|
|
Дата: | 03.02.06 19:19 |
|
Оценка: |
|
Здравствуйте, MaximE, Вы писали:
ME>Fw: An omnipotant swap?
Вопрос: можно ли использовать данный подход для определения наличия методов имеющих различные имена?
Re: Кто хотел определения наличия функции-члена?
Здравствуйте, MaximE, Вы писали:
ME>Fw: An omnipotant swap?
ME>Используется фича компиляторов "Substitution Failure Is Not An Error" (SFINAE), на основе которой в boost'e сейчас разрабатывается инструмент enable_if.
Браво!
C++ рулит
... << RSDN@Home 1.2.0 alpha rev. 634>>
"Всё что не убивает нас, делает нас сильнее..."
Re: Кто хотел определения наличия функции-члена?
|
От: |
Аноним
|
|
Дата: | 15.02.07 18:18 |
|
Оценка: |
|
Здравствуйте, MaximE, Вы писали:
ME>Fw: An omnipotant swap?
ME>ME>
ME>#include <list>
ME>namespace omni{
ME>template <class T, T val>
ME>struct member_wrapper{};
ME>template <class T>
ME>char test_for_swap(const T&, member_wrapper<void (T::*)(T&), &T::swap>* p = 0);
ME>template <class T>
ME>double test_for_swap(const T&, ...);
ME>template <class T>
ME>struct has_member_swap
ME>{
ME> static T t;
ME> static const bool value = (1 == sizeof(test_for_swap(t)));
ME>};
ME>//BOOST_STATIC_ASSERT(has_member_swap<std::list<int>::value);
ME>//BOOST_STATIC_ASSERT(!has_member_swap<int>::value);
ME>//BOOST_STATIC_ASSERT(!has_member_swap<noswap>::value);
ME>template<bool b>
ME>struct swapper
ME>{
ME> template <class T>
ME> static void swap(T& t1, T& t2)
ME> { std::swap(t1, t2); }
ME>};
ME>template<>
ME>struct swapper<true>
ME>{
ME> template <class T>
ME> static void swap(T& t1, T& t2)
ME> { t1.swap(t2); }
ME>};
ME>template <class T>
ME>void swap(T& t1, T& t2)
ME>{
ME> swapper<has_member_swap<T>::value>::swap(t1, t2);
ME>}
ME>} // namespace omni
ME>struct noswap{};
ME>int main()
ME>{
ME> std::list<intl1, l2;
ME> omni::swap(l1, l2);
ME> noswap s1, s2;
ME> omni::swap(s1, s2);
ME> int i1, i2;
ME> omni::swap(i1, i2);
ME> return 0;
ME>}
ME>
ME>Используется фича компиляторов "Substitution Failure Is Not An Error" (SFINAE), на основе которой в boost'e сейчас разрабатывается инструмент enable_if.
Comeau не хочет компилить этот код
Re[2]: Кто хотел определения наличия функции-члена?
|
От: |
gid_vvp
|
|
Дата: | 16.02.07 07:49 |
|
Оценка: |
|
А>Comeau не хочет компилить этот код
т.е. вопрос в следующем:
кто виноват и что делать?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Кто хотел определения наличия функции-члена?
|
От: |
gid_vvp
|
|
Дата: | 16.02.07 09:35 |
|
Оценка: |
|
Здравствуйте, gid_vvp, Вы писали:
А>>Comeau не хочет компилить этот код
_>т.е. вопрос в следующем:
_>кто виноват и что делать?
ларчик просто открывался...
namespace hlp
{
typedef char TySmall;
struct TyBig{ TySmall array[2];};
template <typename T, T val>
struct MemberWrapper{};
template <typename T, typename TyArg>
TySmall TestForCreateWithArg(const T&, TyArg& arg, MemberWrapper<void (T::*)(TyArg), &T::Create>* p = 0);
TyBig TestForCreateWithArg(...);
template <typename T, typename TyArg>
struct HasMemberCreateWithArg
{
static T t;
static TyArg arg;
static const bool value = (sizeof(TySmall) == sizeof(TestForCreateWithArg(t, arg)));
};
}
class A
{
public:
void Create(int){}
};
class B
{
public:
void Create(double){}
void Create(int){}
};
class C
{
};
int a[hlp::HasMemberCreateWithArg<A, int>::value];
int b[hlp::HasMemberCreateWithArg<B, double>::value];
//int c[hlp::HasMemberCreateWithArg<C, int>::value];
только я затрудняюсь сказать на сколько это всё по стандарту...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пока на собственное сообщение не было ответов, его можно удалить.