Switched Return
Essentially what I am liking to do here is make a templated function call where the caller essentially requests a given type and either a pointer or a reference will be passed back. Based on the type given in the template I wish to return the retrieved unadjusted pointer if it is a pointer and if it is a stored value I would like to switch type to reference. I would also like to expand this thought to include references, classes, pointers to classes and so on ...
#include <utility>
#include <type_traits>
using namespace std;
using namespace std::tr1;
template< bool condition, typename Then, typename Else >
struct IF {
typedef typename Then RET;
};
template<typename Then, typename Else >
struct IF< false, Then, Else > {
typedef typename Else RET;
};
template<class T>
struct ReturnType {
typedef typename IF<std::is_pointer<T>::value, T, T& >::RET RET;
};
template<bool condition, typename U>
struct Member {
Member(){ value = 2; member = &value; };
int value;
int* member;
};
temp开发者_运维知识库late<typename U>
struct Member<false, U> {
Member(){ member = 5; };
int member;
};
typedef class tagFOO {
public:
template < typename T >
typename ReturnType<T>::RET function()
{
Member<std::is_pointer<T>::value, T> ret;
return ret.member;
};
} FOO;
int main() {
int i = 0;
int* pi = NULL;
FOO A;
i = A.function<int>();
pi = A.function<int*>();
return 0;
}
This code when ran outputs 5 and 2 respectively.
I guess my first issue with doing this was with defining the return type where I would have liked to have done this
auto function()->decltype(typename ReturnType<T>::RET)
instead. I'm not sure why this doesn't work I just get an unresolved template error in any combination of everything I could possibly imagine.
My second issue is in handling a variety of different return types. This is going to be a bit trialing and, correct me if I'm wrong, a trailing return type would be a quick fix because the compiler seems to ignore the invalid returns. This was something I tested by simply passing ->decltype(T) but I may have made a mistake in my test somewhere.
I think what I have here will be enough to get the job done. I'm sure there are a few opinions on why this might not be such a great idea and I would love to hear those.
thx, BekaD:
Maybe boost::call_traits can help.
http://boost.org/doc/libs/1_45_0/libs/utility/call_traits.htm
精彩评论