Re: How get the specialized Type of after Template
Piaoger Gong wrote:
Hey,
I can get current Class name by the following method:
------------------------------------------------------------------------
#include <string>
typedef std::string SMCPString8;
#define _SMCP_FORCE_NSTRING_(s) #s
Any identifier whose first character is an underscore (such as
_SMCP_FORCE_NSTRING_) has been reserved for use as an
implementation-defined name. So by defining a name reserved for another
party, this program has broken the terms of its C++ "warranty". In
essence the Standard no longer guarantees that this program's behavior
will conform to the behavior as defined in the C++ Standard. The
Standard withdrew its warranty because there is nothing left to prevent
the program's misappropriated identifier from conflicting or otherwise
interfering with one of the implementation's own identifiers. In short,
all bets are off.
_SMCP_FORCE_NSTRING_ is not
#define DECLARE_CLASS(classname) \
public: \
SMCPString8 GetClassName() const { return
_SMCP_FORCE_NSTRING_(classname);}
Purely in terms of programming style, I do not see in what way
SMCPString8 is a better name than std:: string - or even that this
typedef accomplishes anything other than to make reading this code,
more difficult.
class CTestClass
{
public:
CTestClass(){}
~CTestClass(){ }
DECLARE_CLASS(CTestClass)
};
I can see several drawbacks with this DECLARE_CLASS macro as the
mechanism to obtain a string with the name of a specified type. For
one, even though the DECLARE_CLASS macro is found inside its target
class's declaration, the program must still specify the name of the
enclosing class name as a parameter. And having to specify the class
name in the midsts of its definition seems likely to prove as
error-prone as it is redundant - or perhaps even more so, since passing
a mismatched class name to a DECLARE_CLASS macro is an error that goes
undetected. Two, the very fact that that the DECLARE_CLASS macro must
be inserted into the body of a class declaration - sharply limits the
scope of this solution to just name strings for the program's own class
types. Three, DECLARE_CLASS works only with class types - it cannot,
for instance, get the name string for a fundamental or a template
specialization type..
Is it possible to get the specified argument type of Template?
------------------------------------------------------------------------
template<class ClassType>
class CTemplateClass
{
SMCPString8 GetClassType(){ ....... }
}
Yes. Even though it's not possible to write a solution that eliminates
macro use entirely, it is at least possible to write one that remedies
the shortcomings (noted above) of the current implementation
Specifically, this solution should a) require each class name be
specified just once - and have this one-time class specifcation be free
of any redundant or error-prone dependencies on any other declarations
b) require no changes be made to any class definition c) work with
class, fundamental and template specialization types.
So here it is:
#include <iostream>
#include <vector>
#include <string>
// ClassName pairs a type T with
// with its typename as a string
template <class T>
struct ClassName
{
static const char * name;
};
// The following macros create specializations of ClassName
// use CLASSNAME with unqualified typenames
#define CLASSNAME(x) \
template<> const char * ClassName<x>::name = #x
// use QCLASSNAME with (singly) qualified typenames
#define QCLASSNAME(ns, x) \
template<> const char * ClassName<ns :: x>::name = #ns "::"#x
// Example:
CLASSNAME(long);
QCLASSNAME(std, string);
QCLASSNAME(std, vector<int> );
int main()
{
std::cout << ClassName< long >::name << "\n";
std::cout << ClassName< std::string >::name << "\n";
std::cout << ClassName< std::vector<int> >::name << "\n";
}
Program Output:
long
std::string
std::vector<int>
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]