Template for return-type
-
Currently, there is no general solution for this problem. Here we need to determine the type from an expression without evaluating that expression (in order to use it in a declaration), however, some compilers do have extensions to make that possible (__typeof). If the set of possible types is known, a solution exists using some nifty template techniques in conjunction with sizeof. In that case, boost's typeof library is viable:
// helper-template, no definition required template<typename T> const T& make(); // BOOST_TYPEOF_TPL( T() * T() ) cannot handle types that are not default-constructible template<typename T> BOOST_TYPEOF_TPL( make<T>() * make<T>() ) sqr(const T& x) { return x * x; }
In the upcoming standard, this problem shall have an elegant solution:
template<typename T> constexpr sqr(T&& x) -> decltype( x * x ) { return x * x; }
-
you could provide a helper template
teplate <typename T> struct SquaredType { typedef T ResultType; //normally T*T gives another T }; template<> struct SquaredType<3DVector> { typedef Scalar ResultType; //Product of 2 3DVector gives a Scalar }; template <typename T> SquaredType<T>::ResultType Sqr(T const& x) {return x*x;}
now you only have to specialize SquaredType for types where the multiplication gives another type
-
Thanks. How to use __typeof technique?
I thinked for several days and thinked out the following solution:
class cVector { ... public: template<class C> struct tMult{}; template<> struct tMult<cVector>{typedef double type;}; //The type of vector*vector template<> struct tMult<double>{typedef cVector type;}; //The type of vector*double ... };
Now, for all classes which have
tMult
struct I can do the following:template<class A, class B> inline typename A::tMult<B>::type Multiply(A const &a, B const &b) { return a*b; }
P.S.: Why “typedef template is illegal” ?? Why I need to store type in template struct?
-
SAn schrieb:
TP.S.: Why “typedef template is illegal” ?? Why I need to store type in template struct?
Good question. It just is. Again, the next standard will have a solution to this problem (albeit not using the keyword 'typedef' but rather a templated 'using'). At the moment the best way to work around this restriction is by using meta functions – those 'template struct' constructs.
-
-
Konrad Rudolph schrieb:
SAn schrieb:
TP.S.: Why “typedef template is illegal” ?? Why I need to store type in template struct?
Good question. It just is. Again, the next standard will have a solution to this problem (albeit not using the keyword 'typedef' but rather a templated 'using'). At the moment the best way to work around this restriction is by using meta functions – those 'template struct' constructs.
Though even with template aliases you need meta functions in their declarations if these aliases shall, depending on their template parameters, refer to template classes and ordinary types.
.filmor schrieb:
That does not apply here because result_of requires a call-expression, using an operator does not necessarily result in a function call.
-
camper schrieb:
In the upcoming standard, this problem shall have an elegant solution:
template<typename T> constexpr sqr(T&& x) -> decltype( x * x ) { return x * x; }
for the sake of syntacical correctness:
template <typename T> auto constexpr sqrt (T&&x) -> decltype( x*x ) { return x*x; }
-
SAn schrieb:
Thanks. How to use __typeof technique?
depends on how your compiler implements it.
possibly either this way:template <class T> typeof (T() + T()) //or that way (preferably): typeof (*static_cast<T*>(0) + *static_cast<T*>(0)) foo (T const& a, T const& b) { return a + b; }
-
Was ist denn jetzt der Unterschied zwischen tr1::result_of und decltype ?
Fragt
Werner
-
decltype funktioniert immer, nicht nur mit funktionen.
int a(1), b(2), c(3); decltype (a + b * c) d; //int d; decltype (a = 5) e; //int& e; - operator= gibt eine referenz zurück
result_of wird in C++0x übrigens mittels decltype implementiert sein.
(btw. schreibe ich gerade für das magazin einen artikel über die neuen sprachfeatures von C++0x, also einfach bis nächste woche warten
)
-
Hi SAn,
SAn schrieb:
template<class T, class TR> inline TR Sqr(T const &x) { return x*x; }
also does not work
. Compiler error “Cannot deduce template parameter for TR” when trying to call such a function.
I think the order ist wrong.
template<class TR, class T> inline TR Sqr(T const &x) { return x*x; } int main() { int i = 3; double d = Sqr<double>(i); }
If you want the return value it must be on the first place. Then you must explicit determine the first template and the second parameter is deduced by the compiler.
BR,
Markus