Using mem_fun_ref with a proxy object - c++

I'm trying to use std::mem_fun_ref (Yes, the deprecated
version. Reasons below) to call a member function through a proxy.
template<typename T>
struct proxy {
T& operator*() { return *t; }
T* operator->() { return t; }
// no address of etc
T* t;
};
struct A {void foo() {}};
int main()
{
A a;
proxy<A> pa = {&a};
std::mem_fun_ref_t<void, A>
fn = std::mem_fun_ref(&A::foo);
fn(pa); // borks
return 0;
}
This works well with C++11 std::mem_fn but not boost::mem_fn, but
I can use neither of those, as I need to specify the type of the
binder in another place and the type of the resulting binder is
unspecified for boost::mem_fn. This wouldn't be a problem if I could
use decltype but I can't as the code needs to be compatible with
C++03.
What is the easiest way to work around this? A custom
mem_fun_through_proxy?
Edit: Another caveat is that the proxy class cannot be changed.

As Georg recommended, I implemented my own solution. Here is the short version:
// snipped solution: does not include const version and hack for void
// returns
#include <functional>
namespace mine {
template<typename Ret, typename T>
class mem_fun_ref_t : public std::unary_function<T, Ret>
{
public:
explicit
mem_fun_ref_t(Ret (T::*f)())
: f(f) { }
template<typename U>
Ret
operator()(U& u) const
{ return (*u.*f)(); }
Ret
operator()(T& t) const
{ return (t.*f)(); }
private:
Ret (T::*f)();
};
} // mine
template<typename T>
struct proxy {
T& operator*() { return *t; }
T* operator->() { return t; }
// no address of etc
T* t;
};
struct X {
int foo() {return 23;}
};
int main()
{
mine::mem_fun_ref_t<int, X> fn(&X::foo);
X x;
// normal
fn(x);
proxy<X> px = {&x};
fn(px);
return 0;
}

Related

Automatic selection of constructor based on available overloaded versions in Abstract Factory

I am writing an Abstract Factory using C++ templates and was hit by a small obstacle. Namely, a generic class T may provide one or more of the following ways to construct objects:
static T* T::create(int arg);
T(int arg);
T();
I am writing the abstract factory class so that it can automatically try these three potential constructions in the given order:
template <class T>
class Factory {
public:
T* create(int arg) {
return T::create(arg); // first preference
return new T(arg); // this if above does not exist
return new T; // this if above does not exist
// compiler error if none of the three is provided by class T
}
};
How do I achieve this with C++ template? Thank you.
Something along this line should work:
struct S { static auto create(int) { return new S; } };
struct T { T(int) {} };
struct U {};
template<int N> struct tag: tag<N-1> {};
template<> struct tag<0> {};
class Factory {
template<typename C>
auto create(tag<2>, int N) -> decltype(C::create(N)) {
return C::create(N);
}
template<typename C>
auto create(tag<1>, int N) -> decltype(new C{N}) {
return new C{N};
}
template<typename C>
auto create(tag<0>, ...) {
return new C{};
}
public:
template<typename C>
auto create(int N) {
return create<C>(tag<2>{}, N);
}
};
int main() {
Factory factory;
factory.create<S>(0);
factory.create<T>(0);
factory.create<U>(0);
}
It's based on sfinae and tag dispatching techniques.
The basic idea is that you forward the create function of your factory to a set of internal functions. These functions test the features you are looking for in order because of the presence of tag and are discarded if the test fail. Because of sfinae, as long as one of them succeeds, the code compiles and everything works as expected.
Here is a similar solution in C++17:
#include <type_traits>
#include <iostream>
#include <utility>
struct S { static auto create(int) { return new S; } };
struct T { T(int) {} };
struct U {};
template<typename C> constexpr auto has_create(int) -> decltype(C::create(std::declval<int>()), bool{}) { return true; }
template<typename C> constexpr auto has_create(char) { return false; }
struct Factory {
template<typename C>
auto create(int N) {
if constexpr(has_create<C>(0)) {
std::cout << "has create" << std::endl;
return C::create(N);
} else if constexpr(std::is_constructible_v<C, int>) {
std::cout << "has proper constructor" << std::endl;
return new C{N};
} else {
std::cout << "well, do it and shut up" << std::endl;
(void)N;
return C{};
}
}
};
int main() {
Factory factory;
factory.create<S>(0);
factory.create<T>(0);
factory.create<U>(0);
}
Thanks to #StoryTeller and #Jarod42 for the help in this difficult morning.
See it up and running on wandbox.
Okay, thanks to the answer by #skypjack I was able to come up with a more compatible solution that works with pre c++11 compilers. The core idea is the same, i.e. using tag dispatching for ordered testing. Instead of relying on decltype, I used sizeof and a dummy class for SFINAE.
struct S { static auto create(int) { return new S; } };
struct T { T(int) {} };
struct U {};
template<class C, int=sizeof(C::create(0))> struct test_1 { typedef int type; };
template<class C, int=sizeof(C(0))> struct test_2 { typedef int type; };
template<class C, int=sizeof(C())> struct test_3 { typedef int type; };
template<int N> struct priority: priority<N-1> {};
template<> struct priority<0> {};
class Factory {
template<typename C>
C* create(priority<2>, typename test_1<C>::type N) {
return C::create(N);
}
template<typename C>
C* create(priority<1>, typename test_2<C>::type N) {
return new C(N);
}
template<typename C>
C* create(priority<0>, typename test_3<C>::type N) {
return new C();
}
public:
template<typename C>
C* create(int N) {
return create<C>(priority<2>(), N);
}
};
int main() {
Factory factory;
factory.create<S>(0);
factory.create<T>(0);
factory.create<U>(0);
}
Not sure if it is even possible to stuff the sizeof part into the private function signatures; if so, we can get rid of the dummy classes as well.(failed) The slightly ugly part is to use constants (0 in this case) for sizeof operator, which may get tricky if the constructors take arguments of very complicated types.

Get template function type

I'm new in using templates in C++, I want to do different things depending on type used between < and >, so function<int>() and function<char>() won't do the same things.
How can I achieve this?
template<typename T> T* function()
{
if(/*T is int*/)
{
//...
}
if(/*T is char*/)
{
//...
}
return 0;
}
You want to use explicit specialization of your function template:
template<class T> T* function() {
};
template<> int* function<int>() {
// your int* function code here
};
template<> char* function<char>() {
// your char* function code here
};
Create template specializations:
template<typename T> T* function()
{
//general case general code
}
template<> int* function<int>()
{
//specialization for int case.
}
template<> char* function<char>()
{
//specialization for char case.
}
Best practices involves tag dispatch, because specialization is tricky.
Tag dispatch is easier to use quite often:
template<typename T>
T* only_if_int( std::true_type is_int )
{
// code for T is int.
// pass other variables that need to be changed/read above
}
T* only_if_int( std::false_type ) {return nullptr;}
template<typename T>
T* only_if_char( std::true_type is_char )
{
// code for T is char.
// pass other variables that need to be changed/read above
}
T* only_if_char( std::false_type ) {return nullptr;}
template<typename T> T* function()
{
T* retval = only_if_int( std::is_same<T, int>() );
if (retval) return retval;
retval = only_if_char( std::is_same<T, char>() );
return retval;
}
template<class T>
T Add(T n1, T n2)
{
T result;
result = n1 + n2;
return result;
}
For In detail understanding of template, go through the below link:
http://www.codeproject.com/Articles/257589/An-Idiots-Guide-to-Cplusplus-Templates-Part-1
you can define overloaded functions something like this:
#define INTT 0
#define CHARR 1
template<typename T>
T* function()
{
int type;
type = findtype(T);
//do remaining things based on the return type
}
int findType(int a)
{
return INTT;
}
int findType(char a)
{
return CHARR;
}

Accessing a member in a template: how to check if the template is a pointer or not?

Given the following declaration:
template<class T>
class A {
void run(T val) {
val.member ...
}
}
This code works fine if no pointers are used:
A<Type> a;
Type t;
a.run(t);
But using a pointer results in an error:
A<Type*> a;
Type* t = new Type();
a.run(t);
error: request for member ‘member’ which is of non-class type ‘T*’
Obviously in this case the member must be accessed via ->. What's the best way to handle this?
I found a solution on SO: Determine if Type is a pointer in a template function
template<typename T>
struct is_pointer { static const bool value = false; };
template<typename T>
struct is_pointer<T*> { static const bool value = true; };
...
if (is_pointer<T>::value) val->member
else val.member
But this is very verbose. Any better ideas?
You could use a simple pair of overloaded function templates:
template<typename T>
T& access(T& t) { return t; }
template<typename T>
T& access(T* t) { return *t; }
And then use them this way:
access(val).member = 42;
For instance:
template<typename T>
struct A
{
void do_it(T& val)
{
access(val).member = 42;
}
};
struct Type
{
int member = 0;
};
#include <iostream>
int main()
{
A<Type> a;
Type t;
a.do_it(t);
std::cout << t.member << std::endl;
A<Type*> a2;
Type* t2 = new Type(); // OK, I don't like this, but just to show
// it does what you want it to do...
a2.do_it(t2);
std::cout << t2->member;
delete t2; // ...but then, don't forget to clean up!
}
Here is a live example.
The best idea is probably to specialize your class for pointer types.
template<class T>
class A{ ...};
template<>
class A<T*> { //implement for pointers
};
If you feel that this is too verbose, you can use overload a get_ref function:
template<class T> T& get_ref(T & r) {return r;}
template<class T> T& get_ref(T* r) {return *r;}
template<class T>
class A {
void do(T val) {
get_ref(val).member ...
}
}

Converting Polymorphic Wrapper of type T to type U?

Consider the intention behind the following illegal C++11 code:
struct Base
{
template<typename U>
virtual U convert() = 0;
};
template<typename T>
struct Derived : Base
{
T t;
template<typename U>
virtual U convert() { return U(t); }
};
struct Any
{
Base* b;
template<typename U>
operator U() { return b->convert<U>(); }
};
int main()
{
Any a = ...;
string s = a; // s = a->b->t if T is convertible to string
// fails otherwise with compile error or runtime exception
// (either acceptable)
}
Is there a way to achieve the same or similiar effect with legal code?
(fyi the above way is illegal because templates may not be ‘virtual’)
Update:
struct Base
{
void* p;
type_info type;
};
template<typename T>
struct Derived : Base
{
Derived()
{
p = &t; // immovable
type = typeid(T);
}
T t;
};
struct Any
{
Base* b;
template<typename T = U, typename U>
operator U()
{
if (b->type != typeid(T))
throw exception();
T* t = (T*) b->p;
return U(*t);
}
};
Is this what you want?
struct Base
{
virtual void* convert(const std::type_info&) = 0;
};
template<typename T>
struct Derived : Base
{
virtual void* convert(const std::type_info& ti)
{ return typeid(T) == ti ? &t : nullptr; }
T t;
};
struct Any
{
Base* b;
template<typename U>
operator U()
{
if (auto p = b->convert(typeid(U)))
return *static_cast<U*>(p);
throw std::exception();
}
};
As the other answer says, it's hard to know exactly what you want as you've only shown invalid code, not explained what you're trying to achieve.
Edit oh I see now you want it to work for any convertible type, not just exact matches ... then no, you can't turn a type_info back into the type it represents, which would be needed for the derived type to test if the given type_info corresponded to a type that its stored type is convertible to. You need to know the correct type and specify it somehow, either explicitly or implicitly via deduction. If you then want to convert it to another type, you can do that separately:
Any a{ new Derived<int>() };
try {
char c = a; // throws
}
catch (...)
{
}
int i = a; // OK
char c = (int)a; // OK
Based on your update I think that this is what you are trying to do.
#include <typeinfo>
#include <exception>
#include <string>
template <typename T>
struct Any{
T* t;
Any():t(NULL){}
Any(const T& _t){
t=new T(_t);
}
template<typename U>
operator U(){
if(typeid(T)!=typeid(U) || t==NULL)
throw std::exception();
return *t;
}
};
int main (){
Any<std::string> a(std::string("Nothing"));
std::string b=a;
return 0;
};
If this doesn't help please explain in text not code what you are trying to achieve. It'll be useful to tell us also why you want to use those two extra classes Base and Derived.

Getting non-const type in template

I have a template class that can (and sometimes has to) take a const type, but there is a method that returns a new instance of the class with the same type, but should be explicitly non-const. For example, the following code fails to compile
template<class T> class SomeClass {
public:
T val;
SomeClass(T val) : val(val) {}
SomeClass<T> other() {
return SomeClass<T>(val);
}
};
int main() {
SomeClass<const int> x(5);
SomeClass<int> y = x.other();
return 0;
}
because even though there's a copy on val during the constructor, it's copying to the same type - const int. Just like you can distinguish between T and const T in a template, is there a way to distinguish between T and "nonconst T"?
SomeClass<typename std::remove_const<T>::type> other()
{
return SomeClass<typename std::remove_const<T>::type>(val);
}
std::remove_const is from <type_traits> and is C++11. There's probably a boost::remove_const in Boost.TypeTraits, or you can even roll your own. It's also possible to use std::remove_cv.
You can either use std::remove_const if you are using c++ 11. Otherwise, you can use this:
struct <typename T>
struct remove_const
{
typedef T type;
};
struct <typename T>
struct remove_const<const T>
{
typedef T type;
};
Which does the same.
The problem in essence, is that there are two distinct types which are not strictly convertible.
You can use/return std::remove_const from type_traits:
#include <type_traits>
template<class T>
class SomeClass {
public:
T val;
SomeClass(T p) : val(p) {
}
SomeClass<typename std::remove_const<T>::type> other() {
return static_cast<SomeClass<typename std::remove_const<T>::type> >(val);
}
};
int main() {
SomeClass<const int>x(5);
SomeClass<int>y = x.other();
return 0;
}