Per-type compile time constants?

M

mario

Hi!
First of all, sorry for my English, it's not my native tongue.

Anyway, here we go:
suppose I create a class that handles my own custom text strings.
No, suppose I create TWO such classes, which differ e.g. in the
characters mappings and in the implementation, etc...

Necessary operators are overloaded, so that the following example
works as one may intuitively expect it to work:

MyFirstType MyFirstTypeInstanceA, MyFirstTypeInstanceB;
MySecondType MySecondTypeInstanceA,MySecondTypeInstanceB;

MyFirstTypeInstanceA=GetFirstTypeString();
MySecondTypeInstanceA=GetSecondTypeString();

MyFirstTypeInstanceB="Hello"+MyFirstTypeInstanceA+NewLine;
MySecondTypeInstanceB="Hello"+MySecondTypeInstanceA+NewLine;

Please focus on "NewLine". My problem is the following:

I want NewLine to be a *different* constant in the two cases
of above. The compiler knows, in the first case, that it is
evaluating an expression of type "MyFirstType" because it is
assigning the expression to an instance of that type. It also
knowns, in the second case, that this time it is evaluating
an expression of type MySecondType. So it has enough info to
understand that NewLine, if declared as constant, belongs to
its own class each time it evaluates a certain expression.
But I don't know if C++ allows this, hence this post of mine.

Sure, I could do something like:
MyFirstTypeInstanceA="Hello"+MyFirstType::NewLine;
MySecondTypeInstanceA="Hello"+MySecondType::NewLine;

(I made them shorter to avoid the 78 chars Usenet limitation)

But it seems awkward to me to have to specify the type before
the constant, when e.g. the "Hello" conversion from char to
the right type is automaticly handled in an nice way by the
compiler.

Is there any way in C++ to make a (preferably compile time,
for performance reasons) constant depend on the "context" (I
mean on the type that is being evaluated in the expression)?

Sorry again for my English, it's not my native language.

Thanks a lot,
Mario
 
K

Kai-Uwe Bux

Hi!
First of all, sorry for my English, it's not my native tongue.

Anyway, here we go:
suppose I create a class that handles my own custom text strings.
No, suppose I create TWO such classes, which differ e.g. in the
characters mappings and in the implementation, etc...

Necessary operators are overloaded, so that the following example
works as one may intuitively expect it to work:

MyFirstType MyFirstTypeInstanceA, MyFirstTypeInstanceB;
MySecondType MySecondTypeInstanceA,MySecondTypeInstanceB;

MyFirstTypeInstanceA=GetFirstTypeString();
MySecondTypeInstanceA=GetSecondTypeString();

MyFirstTypeInstanceB="Hello"+MyFirstTypeInstanceA+NewLine;
MySecondTypeInstanceB="Hello"+MySecondTypeInstanceA+NewLine;

Please focus on "NewLine". My problem is the following:

I want NewLine to be a *different* constant in the two cases
of above. The compiler knows, in the first case, that it is
evaluating an expression of type "MyFirstType" because it is
assigning the expression to an instance of that type. It also
knowns, in the second case, that this time it is evaluating
an expression of type MySecondType. So it has enough info to
understand that NewLine, if declared as constant, belongs to
its own class each time it evaluates a certain expression.
But I don't know if C++ allows this, hence this post of mine.

Sure, I could do something like:
MyFirstTypeInstanceA="Hello"+MyFirstType::NewLine;
MySecondTypeInstanceA="Hello"+MySecondType::NewLine;

(I made them shorter to avoid the 78 chars Usenet limitation)

But it seems awkward to me to have to specify the type before
the constant, when e.g. the "Hello" conversion from char to
the right type is automaticly handled in an nice way by the
compiler.

Is there any way in C++ to make a (preferably compile time,
for performance reasons) constant depend on the "context" (I
mean on the type that is being evaluated in the expression)?
[snip]

Maybe someting like this (although it maybe overly complicated):

#include <string>
#include <iostream>

struct a_string : private std::string {

a_string ( void )
{}

template < typename A >
a_string ( A const & a )
: std::string( a )
{}

template < typename A, typename B >
a_string ( A const & a, B const & b )
: std::string( a, b )
{}

a_string & operator+= ( a_string const & other ) {
std::string::eek:perator+=( other );
return ( *this );
}

std::string const & str ( void ) const {
return ( *this );
}

};

struct b_string : private std::string {

b_string ( void )
{}

template < typename A >
b_string ( A const & a )
: std::string( a )
{}

template < typename A, typename B >
b_string ( A const & a, B const & b )
: std::string( a, b )
{}

b_string & operator+= ( b_string const & other ) {
std::string::eek:perator+=( other );
return ( *this );
}

std::string const & str ( void ) const {
return ( *this );
}

};

struct new_line_const {

new_line_const ( int )
{}

operator a_string ( void ) const {
return ( a_string( "hello" ) );
}

operator b_string ( void ) const {
return ( b_string( "world" ) );
}

};

static
new_line_const const new_line = 0;

int main ( void ) {
a_string a ( "greetings: " );
a += new_line;
std::cout << a.str() << '\n';

b_string b ( "greetings: " );
b += new_line;
std::cout << b.str() << '\n';
}


Also note that the compiler will perform only one user defined conversion,
so this trick might not work in all circumstances.


Best

Kai-Uwe Bux
 
P

peter koch

(e-mail address removed) skrev:
Hi!
First of all, sorry for my English, it's not my native tongue.

Anyway, here we go:
suppose I create a class that handles my own custom text strings.
No, suppose I create TWO such classes, which differ e.g. in the
characters mappings and in the implementation, etc...

Necessary operators are overloaded, so that the following example
works as one may intuitively expect it to work:

MyFirstType MyFirstTypeInstanceA, MyFirstTypeInstanceB;
MySecondType MySecondTypeInstanceA,MySecondTypeInstanceB;

MyFirstTypeInstanceA=GetFirstTypeString();
MySecondTypeInstanceA=GetSecondTypeString();

MyFirstTypeInstanceB="Hello"+MyFirstTypeInstanceA+NewLine;
MySecondTypeInstanceB="Hello"+MySecondTypeInstanceA+NewLine;

Please focus on "NewLine". My problem is the following:

I want NewLine to be a *different* constant in the two cases
of above. The compiler knows, in the first case, that it is
evaluating an expression of type "MyFirstType" because it is
assigning the expression to an instance of that type. It also
knowns, in the second case, that this time it is evaluating
an expression of type MySecondType. So it has enough info to
understand that NewLine, if declared as constant, belongs to
its own class each time it evaluates a certain expression.
But I don't know if C++ allows this, hence this post of mine.

Sure, I could do something like:
MyFirstTypeInstanceA="Hello"+MyFirstType::NewLine;
MySecondTypeInstanceA="Hello"+MySecondType::NewLine;

(I made them shorter to avoid the 78 chars Usenet limitation)

But it seems awkward to me to have to specify the type before
the constant, when e.g. the "Hello" conversion from char to
the right type is automaticly handled in an nice way by the
compiler.

Is there any way in C++ to make a (preferably compile time,
for performance reasons) constant depend on the "context" (I
mean on the type that is being evaluated in the expression)?

What about something like this sketch:

class NewLine_t {};

NewLine_t NewLine;

template <typename T>
T opeator+(T const& t, NewLine_t) { return t + T::NewLine; }

/Peter
 
J

John Carson

Hi!
First of all, sorry for my English, it's not my native tongue.

Anyway, here we go:
suppose I create a class that handles my own custom text strings.
No, suppose I create TWO such classes, which differ e.g. in the
characters mappings and in the implementation, etc...

Necessary operators are overloaded, so that the following example
works as one may intuitively expect it to work:

MyFirstType MyFirstTypeInstanceA, MyFirstTypeInstanceB;
MySecondType MySecondTypeInstanceA,MySecondTypeInstanceB;

MyFirstTypeInstanceA=GetFirstTypeString();
MySecondTypeInstanceA=GetSecondTypeString();

MyFirstTypeInstanceB="Hello"+MyFirstTypeInstanceA+NewLine;
MySecondTypeInstanceB="Hello"+MySecondTypeInstanceA+NewLine;

Please focus on "NewLine". My problem is the following:

I want NewLine to be a *different* constant in the two cases
of above. The compiler knows, in the first case, that it is
evaluating an expression of type "MyFirstType" because it is
assigning the expression to an instance of that type.

You are supposing that the left-hand side of the assignment should influence
how the right-hand side is evaluated. It doesn't work like that.
It also
knowns, in the second case, that this time it is evaluating
an expression of type MySecondType. So it has enough info to
understand that NewLine, if declared as constant, belongs to
its own class each time it evaluates a certain expression.
But I don't know if C++ allows this, hence this post of mine.


Kai-Uwe has given a very nice solution. The following fleshes out Peter's
suggestion, which involves overloading operator+

#include <string>
#include <iostream>
using namespace std;


struct NewLine
{};

NewLine new_line;

class stringA : public string
{
public:
static string nl;
stringA()
{}
stringA(const char * cstr) : string(cstr)
{}
stringA(const string & sstr) : string(sstr)
{}
};
string stringA::nl = "Anew_line";

class stringB : public string
{
public:
static string nl;
stringB()
{}
stringB(const char* cstr) : string(cstr)
{}
stringB(const string & sstr) : string(sstr)
{}
};
string stringB::nl = "Bnew_line";

template <typename T>
T operator+(T const& t, NewLine) { return t + T::nl; }


int main()
{
stringA a1("This is a stringA ");
stringB b1("This is a stringB ");
stringA a2;
stringB b2;

a2 = a1 + new_line;
b2 = b1 + new_line;

cout << a2 << endl;
cout << b2 << endl;

return 0;
}
 

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

No members online now.

Forum statistics

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

Latest Threads

Top