 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Guest
|
Posted: Mon Jun 12, 2006 2:38 am Post subject: named function parameters using strong typedefing like mechi |
|
|
This message shows how to make the following code legal C++:
object.set()(Data(1),WithinFoobar(x));
Making C++ look more like the self documenting Objective C. (Though I
think I like having the power of C++ over having the weak typing of
Objective C.)
#include "stdafx.h"
// This program demostrates a way to make strong typedefs in C++. It
is
// unforunate that C++ does not have strong typedef's as well as weak
// typedefs built in. Strong typedefing allow C++ look more like
// Objective C. I would enjoy hearing whether anyone else likes
// this techinque. Of course, some of this might just be considered
// Rube-Goldberg by some, but I really like proxies and the syntax
// of Objective C though I have not programmed in it (just read about
it).
namespace StrongTypedefLibrary
{
// This one allows a constant strong typedef.
template<typename T> class ConstDataReferencer
{
T const& data;
public:
typedef T data_type;
explicit ConstDataReferencer(T const& r) : data(r) {}
T const& get() const { return data; }
};
// This one allows a mutable strong typedef.
template<typename T> class MutableDataReferencer
{
T& data;
public:
typedef T data_type;
explicit MutableDataReferencer(T& r) : data(r) {}
T& get() { return data; }
};
}
// If there were a __UNIQUE__ macro in C++ then a second template
// parameter could be added to the DataReferencer types instead
// of having to encode in the Class, but the Class makes it Unique
// for infix notation but allowing the same parameter names though
// __UNIQUE__ would be better. (Not sure infix is right word here,
// but look at the uses of the operator call for information on what
// I mean.)
#define STRONGTYPEDEF(Class,TYPE,NEWTYPE,DR) \
struct Class { \
typedef StrongTypedefLibrary: R##DataReferencer<TYPE> NEWTYPE; }; \
typedef Class::NEWTYPE NEWTYPE;
// This is a macro that allows the use of one parameter operator calls
// so that parameters may be named like they are named in
// objective C. (Though still a different syntax.)
#define PROXY1(MEMBER,METHOD,TPROXY1) \
class Proxy##METHOD { \
private: TPROXY1::data_type& data; \
public: \
class Proxy##METHOD##Result; \
Proxy##METHOD(TPROXY1::data_type& r) : data(r) {} \
Proxy##METHOD##Result operator()(TPROXY1); \
}; \
Proxy##METHOD METHOD() { return Proxy##METHOD(this->MEMBER); }
// This is a macro that allows the use of two parameter operator calls
// so that parameters may be named like they are named in
// objective C. (Though still a different syntax.)
#define PROXY2(MEMBER1,MEMBER2,METHOD,TPROXY1,TPROXY2) \
class Proxy##METHOD { \
private: \
TPROXY1::data_type& data1; \
TPROXY2::data_type& data2; \
public: \
class Proxy##METHOD##Result; \
Proxy##METHOD(TPROXY1::data_type& d1, TPROXY2::data_type& d2) :
data1(d1), data2(d2) {} \
Proxy##METHOD##Result operator()(TPROXY1, TPROXY2); \
}; \
Proxy##METHOD METHOD() { return Proxy##METHOD(this->MEMBER1,
this->MEMBER2); }
namespace AFineName { class C
{
private:
int first; int second;
public:
C(int f, int s) : first(f), second(s) {}
// Strong typedefs:
STRONGTYPEDEF(InnerDataTypeA, int, FirstInt, Const);
STRONGTYPEDEF(InnerDataTypeB, int, SecondInt, Mutable);
PROXY2(first,second,a,FirstInt,SecondInt);
PROXY1(first,b,FirstInt);
};
// These result classes allow the operator calls to return data.
// It is not possible to have a void operator call (ProxybResult
// is the closest one to NULL as possible.)
class C::Proxya::ProxyaResult {
public:
ProxyaResult const& operator=(ProxyaResult const&)
{ std::cout << "ProxyaResult" << std::endl; return *this; }
};
class C::Proxyb::ProxybResult { };
C::Proxya::ProxyaResult C::Proxya::operator ()(C::FirstInt fi,
C::SecondInt si)
{
data1 = fi.get();
data2 = si.get()++;
return ProxyaResult();
}
C::Proxyb::ProxybResult C::Proxyb::operator ()(C::FirstInt fi)
{
data = fi.get();
return ProxybResult();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
AFineName::C area(1,2);
int second = 13;
AFineName::C::Proxya::ProxyaResult result;
{ using namespace AFineName;
// Is this not pretty syntax:
result = area.a()(C::FirstInt(10),C::SecondInt(second));
// And this too:
area.b()(C::FirstInt(201));
}
// Will be 14.
std::cout << second << std::endl;
return 0;
}
// Sincerely, Mark Barkell 2006 AD June 11. 2:49 AM
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Guest
|
Posted: Wed Jun 14, 2006 3:31 am Post subject: Re: named function parameters using strong typedefing like m |
|
|
It can be even nicer than
| Quote: | object.set()(Data(1),WithinFoobar(x));
by just using the operator call |
namespace AFineName {
struct C {
class SetAtInt { ... };
class WithString { ... };
void operator()(SetAsInt sai, WithString str);
};
}
int main()
{
AFineName::C c;
using namespace AFineName;
c(C::SetAsInt(10), C::WithString("hello")); // notice just using the
operator call instead
// of a
named function.
return 0;
}
There may still be better solutions.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|