typedef with template deduction...
От: Caracrist https://1pwd.org/
Дата: 27.12.09 13:43
Оценка:
template<typename T>
struct S
{
typedef T resultT;
void foo(resultT&t);
};

template<typename T>
void xxx_foo(typename S<T>::resultT&t)
{
t = T();
}
void xxx_foo(S<double>::resultT&t)
{
t = -1;
}
template<typename T>
void S<T>::foo(typename S<T>::resultT&t)
{
xxx_foo<T>(t);
}



int main()
{
double dd;
S<double> s;
s.foo(dd);
S<void*> s2 ;
void* vp;
s2.foo(vp);
cout << dd << endl << vp;
return 0;
}

нужно на выходе получить -1 для double и значение по умолчанию для всех остальных. При этом используется не сам тип double в сигнатуре функций, а локальный typedef, который по воле случая к нему приводится.
Этот частный случай можно обойти. Вопрос как вообще это правильно делается?
Речь идёт о том когда для некоторых шаблонных функций нужна спецяльная реализация, и для остальных общая, но при этом типы заданы через typedef.
~~~~~
~lol~~
~~~ Single Password Solution
Re: typedef with template deduction...
От: Angler Россия  
Дата: 27.12.09 15:19
Оценка:
Здравствуйте, Caracrist, Вы писали:

C>нужно на выходе получить -1 для double и значение по умолчанию для всех остальных. При этом используется не сам тип double в сигнатуре функций, а локальный typedef, который по воле случая к нему приводится.

C>Этот частный случай можно обойти. Вопрос как вообще это правильно делается?
C>Речь идёт о том когда для некоторых шаблонных функций нужна спецяльная реализация, и для остальных общая, но при этом типы заданы через typedef.

Частичных специализаций функций вроде как нет в языке. Попробуйте использовать частичную специализацию классов:


template<typename T> struct xxx;

template<typename U>
struct xxx<S<U>>
{    
    static void foo(U &t)
    {
        t = U();
    }
};


template<>
struct xxx<S<double>>
{
    static void foo(double &t)
    {
        t = -1;
    }
};


template<typename T>
void S<T>::foo(typename S<T>::resultT &t)
{
    xxx<S<T>>::foo(t);
}
Re: typedef with template deduction...
От: max-maxtor Россия www.rsdn.ru
Дата: 27.12.09 16:19
Оценка:
Здравствуйте, Caracrist, Вы писали:

C>
C>template<typename T>
C>struct S
C>{
C>typedef T resultT;
C>void foo(resultT&t);
C>};

C>template<typename T>
C>void xxx_foo(typename S<T>::resultT&t)
C>{
C>t = T();
C>}
C>void xxx_foo(S<double>::resultT&t)
C>{
C>t = -1;
C>}
C>template<typename T>
C>void S<T>::foo(typename S<T>::resultT&t)
C>{
C>xxx_foo<T>(t);
C>}



C>int main()
C>{
C>double dd;
C>S<double> s;
C>s.foo(dd);
C>S<void*> s2 ;
C>void* vp;
C>s2.foo(vp);
C>cout << dd << endl << vp;
C>return 0;
C>}
C>

C>нужно на выходе получить -1 для double и значение по умолчанию для всех остальных. При этом используется не сам тип double в сигнатуре функций, а локальный typedef, который по воле случая к нему приводится.
C>Этот частный случай можно обойти. Вопрос как вообще это правильно делается?
C>Речь идёт о том когда для некоторых шаблонных функций нужна спецяльная реализация, и для остальных общая, но при этом типы заданы через typedef.


#include <iostream>
using namespace std;

template<typename T>
class A{
public:
    typedef T resultT;
    void m(typename A<T>::resultT &e);
};
template<typename T>
void A<T>::m(typename A<T>::resultT &e){
    e= 0;
}

template<>
class A<double>{
public:
    typedef double resultT;
    void m(A<double>::resultT &m);
};

void A<double>::m(resultT &m){
        m = -1;
}


int _tmain(int argc, _TCHAR* argv[])
{
    int t1;
    A<int> a;
    a.m(t1);
    double t2;
    A<double> b;
    b.m(t2);
    cout << t1 << " " << t2 << endl;
    system("PAUSE");
    return 0;
}



Так пойдёт?
Re: typedef with template deduction...
От: denisko http://sdeniskos.blogspot.com/
Дата: 27.12.09 17:29
Оценка:
Здравствуйте, Caracrist, Вы писали:

Ты мастер вопросы формулировать, конечно. Тебе нужно получить -1 для всех double и его typedefов или только для дабла. Если первое, то

template<typename T>
struct TypeWrapper
{
    typedef typename T myType;
    myType default()
    {
        return myType();
    }
};
template<typename T>
TypeWrapper<T> typeReasoner(const typename T& value)
{
    return TypeWrapper<T>();
}


struct TypeFramework
{
    template<typename T>
    TypeFramework(const typename TypeWrapper<T>& function)
    {
        printf("random type \n");
    };
    TypeFramework(const TypeWrapper<double>& function)
    {
        printf("double type \n");
    }
};

    
int _tmain(int argc, _TCHAR* argv[])
{
    typedef double hiddenType;
    double a;
    hiddenType b;
    void* c;
    TypeFramework(typeReasoner(a));
    TypeFramework(typeReasoner(b));
    TypeFramework(typeReasoner(c));
    return 0;
}
<Подпись удалена модератором>
Re: typedef with template deduction...
От: Кодт Россия  
Дата: 27.12.09 18:57
Оценка:
Здравствуйте, Caracrist, Вы писали:

C>нужно на выходе получить -1 для double и значение по умолчанию для всех остальных. При этом используется не сам тип double в сигнатуре функций, а локальный typedef, который по воле случая к нему приводится.


В смысле, тебе нужно получить -1 если шаблон параметризован double?
template<class T> struct resetter
{
  template<class V> static void reset(V& v) { v = V(); }
};
template<> struct resetter<double>
{
  template<class V> static void reset(V& v) { v = -1; }
};

// или так

template<class T> struct initializer
{
  template<class V> static V init() { return V(); }
};
template<> struct initializer<double>
{
  template<class V> static void init() { return -1; }
};

....

template<class T> struct S : resetter<T>
{
  void foo()
  {
    .....
    X x = initializer<T>::init<X>(); // если не унаследовались от инструмента
    // либо
    X x;
    reset(x); // если унаследовались от инструмента
    .....
};

Есть нюансы, связанные с наличием у типа переменной различных конструкторов и операторов присваивания (т.е. можно ли инициализировать и присваивать -1). Если речь идёт только о числовых типах, тогда всё равно, а если о каких-нибудь рукодельных, то нужно уточнить контракт. В зависимости от этого, лучше будет использовать initializer или resetter.

C>Этот частный случай можно обойти. Вопрос как вообще это правильно делается?

C>Речь идёт о том когда для некоторых шаблонных функций нужна спецяльная реализация, и для остальных общая, но при этом типы заданы через typedef.

Лично я — за то, чтобы не устраивать кашу из специализаций внутри шаблона, а вытащить специализируемый код в отдельный шаблон. Что, собственно, и показал.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.