Кто хотел определения наличия функции-члена?
От: MaximE Великобритания  
Дата: 13.09.03 09:57
Оценка: 289 (24)
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: Кто хотел определения наличия функции-члена?
От: WolfHound  
Дата: 16.09.03 05:17
Оценка:
Здравствуйте, MaximE, Вы писали:

КРУТО!!!
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Кто хотел определения наличия функции-члена?
От: _Obelisk_ Россия http://www.ibm.com
Дата: 16.09.03 06:22
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, MaximE, Вы писали:


WH>КРУТО!!!


Ага, только непонятно, ЗАЧЕМ это нужно ??



Душа обязана трудиться! (с) Н.Заболоцкий.
Re[3]: Кто хотел определения наличия функции-члена?
От: MaximE Великобритания  
Дата: 16.09.03 07:33
Оценка:
Здравствуйте, _Obelisk_, Вы писали:

_O_>Ага, только непонятно, ЗАЧЕМ это нужно ??


Вот как раз одно применение найдено — ссылка в начале на omnipotent swap.
Re: Кто хотел определения наличия функции-члена?
От: Dmi3evS Россия http://dmi3s.blogspot.com/
Дата: 17.09.03 18:39
Оценка:
Здравствуйте, 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: Кто хотел определения наличия функции-члена?
От: Chiрset Россия http://merlinko.com
Дата: 03.02.06 22:12
Оценка:
Здравствуйте, 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>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.