How to use decltype to determine add result

With decltype I can do the following:

 template <typename T1, typename T2> auto sum(T1 const & t1, T2 const & T2) -> decltype(t1+t2) { /* ... */ } 

However, in my case, I need to know the type of add without instances of types T1 and T2 . In particular:

 template <typename ValueType> class Matrix { /* ... */ public: template <typename CompatibleType> auto operator+(Matrix<CompatibleType> const & other) -> Matrix<decltype(ValueType+CompatibleType)> { /* ... */ } }; 

Of course decltype(ValueType+CompatibleType) does not work this way. Is there any way to achieve this?

+4
source share
5 answers

Use std::declval<T>(); (C ++ 11):

 #include <utility> template <typename CompatibleType> auto operator+(Matrix<CompatibleType> const & other) -> Matrix<decltype(std::declval<ValueType>() + std::declval<CompatibleType>())> { /* ... */ } 

std::declval returns an rvalue-reference and will only work in unevaluated-context, which decltype happens.

If your compiler does not support this standard, use this pointer trick (which also works only in an invaluable context):

 -> Matrix<decltype(*(ValueType*)(0) + *(CompatibleType*)(0))> // or -> Matrix<decltype(*static_cast<ValueType*>(0) + *static_cast<CompatibleType*>(0))> 
+10
source

You can use std::declval to do this:

 decltype(std::declval<A>()+std::declval<B>)) 
+6
source

You need / want std::declval :

 decltype(std::declval<ValueType>()+std::declval<CompatibleType>()); 
+6
source

std::declval works, but there is a simpler answer hiding inside ... - access to the real element!

Assuming your Matrix class has an at function like std::vector , you can write

 template<typename M> auto operator+(M const & other) -> Matrix<decltype(this->at(0,0) + other.at(0,0))> 

Otherwise, replace at with the correct function name, which is used inside the operator+ body to access individual elements.

This has the additional advantage that it works with any other parameter that provides the necessary access function, it should not be another Matrix<T> at all . This is called duck printing, and that is why you should use the same access function that your function body actually uses.

0
source

A bit late for the party, but as long as ValueType and CompatibleType are POD types or other classes that have an open constructor with no arguments (probably a valid assumption for your use case), you can simply build these types. So

 decltype(ValueType+CompatibleType) 

does not work (as you wrote), but

 decltype(ValueType() + CompatibleType()) 

there is and there is no overhead of execution time (Source: here ). In this case, you do not need std::declval .

Proof: Here

0
source

Source: https://habr.com/ru/post/1485323/


All Articles