Re: [Boost-users] [Serialization] is_serializable trait?
Chris Fairles"
on Fri, 20 Jul 2007 18:03:18 -0400 How can you determine (compile-time) that a class has a serialize function? struct foo { template <typename Archive> void serialize (Archive &, const unsigned int); };
"&foo::serialize" isn't a type and I can't figure out a way to make it a type (besides a typedef in the class) and also a constant expression.
Tried to play around with this as well but theres no substitution failure here and static functions can't be constant expressions (commonnnn c++0x!!)
struct serialize { template <typename T> static void value(T const&) { void(T::*f)(archive::xml_oarchive &, const unsigned int) = &T::template serializearchive::xml_oarchive; (void)f; } };
Basically, in the code below I want to see "GoodGood" printed out and the only thing I can change is Q.
struct A{ void f(int,int){} }; struct B{};
template
struct Q{enum{value=false};}; template<class T> struct Q
{enum{value=true};}; int main(){ if(Q<A>::value) { cout << "Good";} if(!Q<B>::value){ cout << "Good";} }
Help/hints/remotely possible?
You can try something like this. #include <iostream> #include <iomanip> typedef char yes_type; struct no_type { char padding[8]; }; template <class T> struct HasSerializeMember { typedef void (T::*SerializationFun)(int &, unsigned); template <SerializationFun> struct A {}; template <class Q> static yes_type Test(A<&Q::serialize>*); template <class Q> static no_type Test(...); static const bool value = sizeof(Test<T>(0)) == sizeof(yes_type); }; struct A { template <class Stream> void serialize(Stream & strm, unsigned version) {} }; struct B { }; struct C { void serialize() {} }; int main() { using namespace std; cout << boolalpha << HasSerializeMember<A>::value << '\n' // true << HasSerializeMember<B>::value << '\n' // false << HasSerializeMember<C>::value << endl; // false } Regards, Roman Perepelitsa Deutsche Bank Moscow +7 (495) 660-74-08 --- This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden. Please refer to http://www.db.com/en/content/eu_disclosures.htm for additional EU corporate and regulatory disclosures.
Very clever, I would expect some variation of this to end up somewhere in the library itself some day.
Robert Ramey
"Roman Perepelitsa"
Chris Fairles"
on Fri, 20 Jul 2007 18:03:18 -0400 How can you determine (compile-time) that a class has a serialize function? struct foo { template <typename Archive> void serialize (Archive &, const unsigned int); };
"&foo::serialize" isn't a type and I can't figure out a way to make it a type (besides a typedef in the class) and also a constant expression.
Tried to play around with this as well but theres no substitution failure here and static functions can't be constant expressions (commonnnn c++0x!!)
struct serialize { template <typename T> static void value(T const&) { void(T::*f)(archive::xml_oarchive &, const unsigned int) = &T::template serializearchive::xml_oarchive; (void)f; } };
Basically, in the code below I want to see "GoodGood" printed out and the only thing I can change is Q.
struct A{ void f(int,int){} }; struct B{};
template
struct Q{enum{value=false};}; template<class T> struct Q
{enum{value=true};}; int main(){ if(Q<A>::value) { cout << "Good";} if(!Q<B>::value){ cout << "Good";} }
Help/hints/remotely possible?
You can try something like this. #include <iostream> #include <iomanip> typedef char yes_type; struct no_type { char padding[8]; }; template <class T> struct HasSerializeMember { typedef void (T::*SerializationFun)(int &, unsigned); template <SerializationFun> struct A {}; template <class Q> static yes_type Test(A<&Q::serialize>*); template <class Q> static no_type Test(...); static const bool value = sizeof(Test<T>(0)) == sizeof(yes_type); }; struct A { template <class Stream> void serialize(Stream & strm, unsigned version) {} }; struct B { }; struct C { void serialize() {} }; int main() { using namespace std; cout << boolalpha << HasSerializeMember<A>::value << '\n' // true << HasSerializeMember<B>::value << '\n' // false << HasSerializeMember<C>::value << endl; // false } Regards, Roman Perepelitsa Deutsche Bank Moscow +7 (495) 660-74-08 --- This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden. Please refer to http://www.db.com/en/content/eu_disclosures.htm for additional EU corporate and regulatory disclosures. ------------------------------------------------------------------------------ _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks!
I kept trying things with void(A::*serialize)(blah, const unsigned
int) in my test function. Like:
template<typename T>
class IsSerializableClassT {
private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename C> static Two test(...);
template<typename C> static One test(void(C::*)(int,int));
public:
enum { Yes = sizeof(IsClassT<T>::template test<T>(0)) == 1 };
enum { No = !Yes };
};
But, when resolving test(...) vs. the member func pointer, it picks
the mem func pointer for any class even if it doesn't have a func with
that specific signature.
That local tempalte trick you use solves the issue. A local template
with a non-type member-function parameter (which i only recently
learned was even possible!), void(T::*)(int&,int)....
So the substitution fails if the supplied fuction doesn't match the
signature. So whats the technical reason why the substitution doesn't
fail based on mem func ptr signature in a function parameter? I guess
function arguments aren't bound until runtime so it never really looks
in the class for the function at compile time?
Chris
On 7/23/07, Robert Ramey
Very clever, I would expect some variation of this to end up somewhere in the library itself some day.
Robert Ramey
"Roman Perepelitsa"
wrote in message news:OFC1A16EC6.69CEAA30-ONC3257321.002322F2-C3257321.0023748C@db.com... Chris Fairles"
on Fri, 20 Jul 2007 18:03:18 -0400 How can you determine (compile-time) that a class has a serialize function? struct foo { template <typename Archive> void serialize (Archive &, const unsigned int); };
"&foo::serialize" isn't a type and I can't figure out a way to make it a type (besides a typedef in the class) and also a constant expression.
Tried to play around with this as well but theres no substitution failure here and static functions can't be constant expressions (commonnnn c++0x!!)
struct serialize { template <typename T> static void value(T const&) { void(T::*f)(archive::xml_oarchive &, const unsigned int) = &T::template serializearchive::xml_oarchive; (void)f; } };
Basically, in the code below I want to see "GoodGood" printed out and the only thing I can change is Q.
struct A{ void f(int,int){} }; struct B{};
template
struct Q{enum{value=false};}; template<class T> struct Q
{enum{value=true};}; int main(){ if(Q<A>::value) { cout << "Good";} if(!Q<B>::value){ cout << "Good";} }
Help/hints/remotely possible?
You can try something like this.
#include <iostream> #include <iomanip>
typedef char yes_type;
struct no_type { char padding[8]; };
template <class T> struct HasSerializeMember { typedef void (T::*SerializationFun)(int &, unsigned);
template <SerializationFun> struct A {};
template <class Q> static yes_type Test(A<&Q::serialize>*);
template <class Q> static no_type Test(...);
static const bool value = sizeof(Test<T>(0)) == sizeof(yes_type); };
struct A { template <class Stream> void serialize(Stream & strm, unsigned version) {} };
struct B { };
struct C { void serialize() {} };
int main() { using namespace std; cout << boolalpha << HasSerializeMember<A>::value << '\n' // true << HasSerializeMember<B>::value << '\n' // false << HasSerializeMember<C>::value << endl; // false }
Regards, Roman Perepelitsa
Deutsche Bank Moscow +7 (495) 660-74-08
---
This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.
Please refer to http://www.db.com/en/content/eu_disclosures.htm for additional EU corporate and regulatory disclosures.
________________________________
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I also took a stab at making a boostified version:
#include <iostream>
#include
Thanks!
I kept trying things with void(A::*serialize)(blah, const unsigned int) in my test function. Like:
template<typename T> class IsSerializableClassT { private: typedef char One; typedef struct { char a[2]; } Two; template<typename C> static Two test(...); template<typename C> static One test(void(C::*)(int,int)); public: enum { Yes = sizeof(IsClassT<T>::template test<T>(0)) == 1 }; enum { No = !Yes }; };
But, when resolving test(...) vs. the member func pointer, it picks the mem func pointer for any class even if it doesn't have a func with that specific signature.
That local tempalte trick you use solves the issue. A local template with a non-type member-function parameter (which i only recently learned was even possible!), void(T::*)(int&,int)....
So the substitution fails if the supplied fuction doesn't match the signature. So whats the technical reason why the substitution doesn't fail based on mem func ptr signature in a function parameter? I guess function arguments aren't bound until runtime so it never really looks in the class for the function at compile time?
Chris
On 7/23/07, Robert Ramey
wrote: Very clever, I would expect some variation of this to end up somewhere in the library itself some day.
Robert Ramey
"Roman Perepelitsa"
wrote in message news:OFC1A16EC6.69CEAA30-ONC3257321.002322F2-C3257321.0023748C@db.com... Chris Fairles"
on Fri, 20 Jul 2007 18:03:18 -0400 How can you determine (compile-time) that a class has a serialize function? struct foo { template <typename Archive> void serialize (Archive &, const unsigned int); };
"&foo::serialize" isn't a type and I can't figure out a way to make it a type (besides a typedef in the class) and also a constant expression.
Tried to play around with this as well but theres no substitution failure here and static functions can't be constant expressions (commonnnn c++0x!!)
struct serialize { template <typename T> static void value(T const&) { void(T::*f)(archive::xml_oarchive &, const unsigned int) = &T::template serializearchive::xml_oarchive; (void)f; } };
Basically, in the code below I want to see "GoodGood" printed out and the only thing I can change is Q.
struct A{ void f(int,int){} }; struct B{};
template
struct Q{enum{value=false};}; template<class T> struct Q
{enum{value=true};}; int main(){ if(Q<A>::value) { cout << "Good";} if(!Q<B>::value){ cout << "Good";} }
Help/hints/remotely possible?
You can try something like this.
#include <iostream> #include <iomanip>
typedef char yes_type;
struct no_type { char padding[8]; };
template <class T> struct HasSerializeMember { typedef void (T::*SerializationFun)(int &, unsigned);
template <SerializationFun> struct A {};
template <class Q> static yes_type Test(A<&Q::serialize>*);
template <class Q> static no_type Test(...);
static const bool value = sizeof(Test<T>(0)) == sizeof(yes_type); };
struct A { template <class Stream> void serialize(Stream & strm, unsigned version) {} };
struct B { };
struct C { void serialize() {} };
int main() { using namespace std; cout << boolalpha << HasSerializeMember<A>::value << '\n' // true << HasSerializeMember<B>::value << '\n' // false << HasSerializeMember<C>::value << endl; // false }
Regards, Roman Perepelitsa
Deutsche Bank Moscow +7 (495) 660-74-08
---
This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.
Please refer to http://www.db.com/en/content/eu_disclosures.htm for additional EU corporate and regulatory disclosures.
________________________________
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
Chris Fairles
-
Robert Ramey
-
Roman Perepelitsa