помогите победить компилятор от MSVC 2010
От: Bork СССР  
Дата: 19.06.15 05:33
Оценка:
Здравствуйте коллеги,

есть код:

#include <type_traits>

struct A
{
};

template <class Y>
struct B
{
    typedef Y _Type;
    A a;
};

struct C
{
    C() {}
    B<int> a;
    B<double> b;
};

template <class T>
void do_something(T val);

template<>
void do_something<A>(A val)
{

}

template <class T>
void do_something(typename std::enable_if<std::is_same<T, B<typename T::_Type> >::value, T>::type val)
{
    do_something<A>(val.a);
}

template<>
void do_something<C>(C val)
{
    do_something< B<int> >(val.a);
    do_something< B<double> >(val.b);
} // <-------- компилятор показывает сюда

int main(int argc, char* argv[])
{
    A a;
    B<int> b;
    B<double> b1;
    C c;

    do_something< A >(a);
    do_something< B<int> >(b);
    do_something< B<double> >(b1);
    do_something< C >(c);
}


он компилируется и работает как ожидается в GCC (4.8.1 +) и в MSVC 2013.
Но надо MSVC 2010, в которой компиляция падает с ошибкой:

error C2794: '_Type' : is not a member of any direct or indirect base class of 'C'

как убедить компилятор, не определяя специализаций всех возможных видов do_something для типа В?
Re: помогите победить компилятор от MSVC 2010
От: night beast СССР  
Дата: 19.06.15 06:45
Оценка:
Здравствуйте, Bork, Вы писали:

B>Здравствуйте коллеги,


B>он компилируется и работает как ожидается в GCC (4.8.1 +) и в MSVC 2013.

B>Но надо MSVC 2010, в которой компиляция падает с ошибкой:

B>error C2794: '_Type' : is not a member of any direct or indirect base class of 'C'


B>как убедить компилятор, не определяя специализаций всех возможных видов do_something для типа В?


на MSVC 2010 проверить не могу. попробуй:
template< typename T > struct is_B { enum { value = 0 }; };
template< typename T > struct is_B< B< T > > { enum { value = 1 }; };

template <class T> void do_something ( typename std::enable_if< is_B< T >::value, T >::type val );


или это не совсем то, что хотелось?
Re[2]: помогите победить компилятор от MSVC 2010
От: Bork СССР  
Дата: 19.06.15 07:40
Оценка:
Здравствуйте, night beast, Вы писали:

NB>или это не совсем то, что хотелось?


К сожалению это не то (типы Т и B<Y> никак не связаны вообще, кроме того что T содержит B<Y> как поле структуры), но за идею спасибо, поковыряю в этом направлении ..
Re[3]: помогите победить компилятор от MSVC 2010
От: night beast СССР  
Дата: 19.06.15 09:01
Оценка:
Здравствуйте, Bork, Вы писали:

NB>>или это не совсем то, что хотелось?


B>К сожалению это не то (типы Т и B<Y> никак не связаны вообще, кроме того что T содержит B<Y> как поле структуры), но за идею спасибо, поковыряю в этом направлении ..


тогда так:

template< typename T, typename t = std::true_type > struct is_b { enum { value = 0 }; };
template< typename T > struct is_b< T, typename std::is_same< T, B< typename T::_Type > >::type > { enum { value = 1 }; };
Re: помогите победить компилятор от MSVC 2010
От: Chorkov Россия  
Дата: 19.06.15 13:43
Оценка:
Здравствуйте, Bork, Вы писали:

B>Здравствуйте коллеги,

B> ...
B>как убедить компилятор, не определяя специализаций всех возможных видов do_something для типа В?

А обязательно использовать именно std::enable_if, вместо обычной специализации?


template <class T>
void do_something(B<T> val);
void do_something(A val);
void do_something(C val);

void do_something(A val)
{

}

template <class T>
void do_something(B<T> val)
{
    do_something(val.a);
}


void do_something(C val)
{
    do_something(val.a);
    do_something(val.b);
} 

int main(int argc, char* argv[])
{
    A a;
    B<int> b;
    B<double> b1;
    C c;

    do_something(a);
    do_something(b);
    do_something(b1);
    do_something(c);
}
Re[2]: помогите победить компилятор от MSVC 2010
От: Bork СССР  
Дата: 19.06.15 16:34
Оценка:
Здравствуйте, Chorkov, Вы писали:

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


B>>Здравствуйте коллеги,

B>> ...
B>>как убедить компилятор, не определяя специализаций всех возможных видов do_something для типа В?

C>А обязательно использовать именно std::enable_if, вместо обычной специализации?


Не обязательно, просто обычных специализаций получится под сотню, вместо одного шаблона с std::enable_if. Жаль что требования обязывают поддерживать 2010 студию...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.