How to define operator "const char *" of enumerated type defined inside a class

B

Bill Davy

I want to be able to write (const char*)v where v is an item of type
Class::ToolTypeT where ToolTypeT is an enumeration and I've tried
everything that looks sensible. There's an ugly solution, but surely this is
possible?



I could define an operator<< but for various reasons, I really want to
convert to a 'const char*' (to embed into a string which becomes part of a
window's caption, etc).



TIA,

Bill



class Class

{

public :

typedef enum {tt_SLBTool = 0, tt_DMM1, tt_ MAX 010} ToolTypeT;

// friend operator const char*(const Class::ToolTypeT &v); //
'operator const char *' must be a non-static member

// static operator const char*(const Class::ToolTypeT &v); //
'Class::eek:perator const char *' must be a non-static member

};



// extern operator const char*(const Class::ToolTypeT &v); // 'operator
const char *' must be a non-static member

extern const char * Map( const Class::ToolTypeT &v); // But this is so ugly



This is what I want to write:

Class ClassObject;

..

const Class::ToolTypeT v=ClassObject.GetType();

CString str.

Str.Format("%s: version .",(const char*)v);

SetWindowText(str);
 
A

anon

Bill said:
I want to be able to write (const char*)v where v is an item of type
Class::ToolTypeT where ToolTypeT is an enumeration and I've tried
everything that looks sensible. There's an ugly solution, but surely this is
possible?



I could define an operator<< but for various reasons, I really want to
convert to a 'const char*' (to embed into a string which becomes part of a
window's caption, etc).



TIA,

Bill



class Class

{

public :

typedef enum {tt_SLBTool = 0, tt_DMM1, tt_ MAX 010} ToolTypeT;

// friend operator const char*(const Class::ToolTypeT &v); //
'operator const char *' must be a non-static member

// static operator const char*(const Class::ToolTypeT &v); //
'Class::eek:perator const char *' must be a non-static member

};



// extern operator const char*(const Class::ToolTypeT &v); // 'operator
const char *' must be a non-static member

extern const char * Map( const Class::ToolTypeT &v); // But this is so ugly



This is what I want to write:

Class ClassObject;

.

const Class::ToolTypeT v=ClassObject.GetType();

CString str.

Str.Format("%s: version .",(const char*)v);

SetWindowText(str);

Not sure what exactly is CString and how you define it, but this example
is doing what you want:



////////////////////////////////////
#include <iostream>
class a
{
public:

operator const char*();
};
a::eek:perator const char* ()
{
return "a";
}
int main()
{
a obj;
const char* s = obj;
std::cout<<s<<std::endl;
}
 
B

Bill Davy

anon said:
Not sure what exactly is CString and how you define it, but this example
is doing what you want:



////////////////////////////////////
#include <iostream>
class a
{
public:

operator const char*();
};
a::eek:perator const char* ()
{
return "a";
}
int main()
{
a obj;
const char* s = obj;
std::cout<<s<<std::endl;
}

Thanks for this, but my goal is a conversion operator for an enumerated type
defined inside a class, not the class itself. But thanks for the
suggestion.

Rgds
Bill
 
B

Bill Davy

I want to be able to write (const char*)v where v is an item of type
Class::ToolTypeT where ToolTypeT is an enumeration and I've tried
everything that looks sensible. There's an ugly solution, but surely this
is
possible?


You can't really do this with merely an enum. You can, however, define a
class that, essentially, acts like an enum.

class Class {

public:

static const int a=0;
static const int b=1;
static const int c=2;

class ToolTypeT {
int v;

public:
ToolTypeT(int i): v(i) {}

ToolType &operator=(int i) { v=i; return *this; }

operator int() const { return v; }

operator const char *();
};
};

You can use this Class::ToolTypeT pretty much like an enumeration. Class::a,
Class::b, Class::c, etc. are your enumerator values. And, you can supply a
meaningful operator const char *().

And, with a few more tweaks, you can add additional type-safety to the whole
schema.



Bill Davy writes:

That's an interesting approach. Can switch on ToolTypeT which is good. Can
even make a,b,c into an eunumeration (which may help some tools notice if I
have missed one out). And the type conversion is there.

Many thanks,
Bill
 
J

James Kanze

I want to be able to write (const char*)v where v is an item
of type Class::ToolTypeT where ToolTypeT is an enumeration and
I've tried everything that looks sensible. There's an ugly
solution, but surely this is possible?

It's not, and you almost certainly don't want to do it anyway.
I could define an operator<< but for various reasons, I really
want to convert to a 'const char*' (to embed into a string
which becomes part of a window's caption, etc).

The usual way of generating such strings is to use an
std::eek:stringstream. Anything else reeks of abuse or poor
design.
 
B

Bill Davy

I want to be able to write (const char*)v where v is an item
of type Class::ToolTypeT where ToolTypeT is an enumeration and
I've tried everything that looks sensible. There's an ugly
solution, but surely this is possible?

It's not, and you almost certainly don't want to do it anyway.
I could define an operator<< but for various reasons, I really
want to convert to a 'const char*' (to embed into a string
which becomes part of a window's caption, etc).

The usual way of generating such strings is to use an
std::eek:stringstream. Anything else reeks of abuse or poor
design.

--
James Kanze (GABI Software) email:[email protected]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

---
So, I define operator<< and a template:

template string Stringify(const T &v)
{
ostringstream;
os << v << ends;
return os.str();
}

I'm not sure that's better than what I wanted to do, is it? A reader can
see what (const char*)t does and it is idiomatic.

I do not want to be accused of premature optimisation, but this solution
goes a long way round the houses (oops, another idiom) to turn 1 into "DMM".

But YMMV.

Bill
 
J

James Kanze

So, I define operator<< and a template:
template string Stringify(const T &v)
{
ostringstream;
os << v << ends;
return os.str();
}

Why a template?
I'm not sure that's better than what I wanted to do, is it?
A reader can see what (const char*)t does and it is idiomatic.

It's certainly not idiomatic, and it's already defined for enum
types---with a meaning that certainly isn't what you want.
(It's a reinterpret_cast.) In general, implicit conversions to
char const* (or to other pointer types) are to be avoided.
I do not want to be accused of premature optimisation, but
this solution goes a long way round the houses (oops, another
idiom) to turn 1 into "DMM".

It's not a question of optimization or whatever. The idiomatic
method of streaming data in C++ is to use operator<<, defining
operator<< for whatever types need streaming. Anything else is
obfuscation. That doesn't mean that it isn't worthwhile to
provide a general function for obtaining a symbolic value, as a
string, from an enum value---if nothing else, you could use it
to implement the operator<<. But the conversion shouldn't be
implicit. You want a named function.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top