473,471 Members | 1,716 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Constness Complications


Here's two functions, a "const version" and a "non-const version":
char* GetFirstT(char* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}

return 0;
}

const char* GetFirstT(const char* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}

return 0;
}

signed main()
{
char the_alphabet[] = "abcdefghijklmnopqrstuvwxyz";

char* p_t = GetFirstT(the_alphabet);
}
See how I have to define two functions, is there any handy around that?
Would I have to do the following:

const char* GetFirstT(const char* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}

return 0;
}

char* GetFirstT(char* p)
{
return const_cast<char*>( GetFirstT(p) );
}
-JKop

Jul 22 '05 #1
14 1457
JKop <NU**@NULL.NULL> wrote in news:i9******************@news.indigo.ie:

Here's two functions, a "const version" and a "non-const version":
char* GetFirstT(char* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}

return 0;
}

const char* GetFirstT(const char* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}

return 0;
}

signed main()
{
char the_alphabet[] = "abcdefghijklmnopqrstuvwxyz";

char* p_t = GetFirstT(the_alphabet);
}
See how I have to define two functions, is there any handy around that?


No, you dont need to define both of them. See below.

#include <iostream>

char const* get_first_of(char const* s, char c)
{
for (; *s && *s != c; ++s);
return s;
}

int main()
{
char s[] = "abcdefghijklmnopqrstuvwxyz";
const char cs[] = "abcdefghijklmnopqrstuvwxyz";

const char* p1 = get_first_of(s, 'c');
const char* p2 = get_first_of(cs, 't');

std::cout << p1 << '\n'
<< p2 << '\n';

return 0;
}

When a function specifies its argument as const, it clearly means that it
won't modify that. Const-specifier can be implicitly hooked on.

Cheers.
--
:: bartekd / o2 pl
:: "out of confusion comes chaos -- out of chaos comes confusion and fear
:: -- then comes lunch."

Jul 22 '05 #2
JKop wrote:
See how I have to define two functions, is there any handy around that?
Would I have to do the following:

const char* GetFirstT(const char* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}

return 0;
}

char* GetFirstT(char* p)
{
return const_cast<char*>( GetFirstT(p) );
}


Why don't you use templates?

template<typename CHARTYPE>
CHARTYPE* GetFirstT(CHARTYPE* p)
{
....
}
--
Regards,
Tobias
Jul 22 '05 #3
JKop wrote:
Here's two functions, a "const version" and a "non-const version":
char* GetFirstT(char* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}

return 0;
}

const char* GetFirstT(const char* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}

return 0;
}

signed main()
{
char the_alphabet[] = "abcdefghijklmnopqrstuvwxyz";

char* p_t = GetFirstT(the_alphabet);
}
See how I have to define two functions, is there any handy around that?
Would I have to do the following:

const char* GetFirstT(const char* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}

return 0;
}

char* GetFirstT(char* p)
{
return const_cast<char*>( GetFirstT(p) );
}
-JKop


Hello,

what about using template?

template <class charT>
charT* GetFirstT(charT* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}
return 0;
}

signed main()
{
char the_alphabet[] = "abcdefghijklmnopqrstuvwxyz";

char* p_t = GetFirstT<char>(the_alphabet);
}

This way you can create GetFirstT() even for wchar and const wchar. Even
better would force use of character_traits, but this is too much for me.
Maybe someone else will know...

Ales
Jul 22 '05 #4
AlesD wrote:

Hello,

what about using template?

Templates aren't appropriate here.
template <class charT>
charT* GetFirstT(charT* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}
return 0;
}

signed main()
{
char the_alphabet[] = "abcdefghijklmnopqrstuvwxyz";

char* p_t = GetFirstT<char>(the_alphabet);
}

This way you can create GetFirstT() even for wchar and const wchar.


Well, you'd get code that compiles and runs. But what does *p == 't'
tell you when the type of p is wchar_t*? There is no requirement that
L't' == 't'.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #5
Tobias Güntner posted:
JKop wrote:
See how I have to define two functions, is there any handy around that? Would I have to do the following:

const char* GetFirstT(const char* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}

return 0;
}

char* GetFirstT(char* p)
{
return const_cast<char*>( GetFirstT(p) ); }


Why don't you use templates?

template<typename CHARTYPE>
CHARTYPE* GetFirstT(CHARTYPE* p)
{
...
}

That template is non-const.
-JKop

Jul 22 '05 #6

Just to elaborate more on that. While this function doesn't edit any
objects; if possible I want to be able to return a non-const pointer, as the
user may want to then use it for something.

I'm looking for using the same body of code for multiple functions. Like
imagine something like this:

body Blah
{
//code
}

char* FuncName(char*)
using body Blah;

const char* FunctName2(const char*)
using body Blah;
Looks like I've only got two options: either copy and paste and actually
make two functions. The only pickle I have with this is maintaining two
functions, plus added compile time.

Who here would go with the const_cast version?
-JKop

-JKop
Jul 22 '05 #7
"JKop" <NU**@NULL.NULL> wrote in message
news:xj******************@news.indigo.ie...
<snip>
I'm looking for using the same body of code for multiple functions. Like
imagine something like this:

body Blah
{
//code
}

char* FuncName(char*)
using body Blah;

const char* FunctName2(const char*)
using body Blah;
Looks like I've only got two options: either copy and paste and actually
make two functions. The only pickle I have with this is maintaining two
functions, plus added compile time.

Who here would go with the const_cast version?


I've done it before, and I would do it again. I don't know of anything that
would cause problems when using that technique.

--
David Hilsee
Jul 22 '05 #8
JKop <NU**@NULL.NULL> wrote in news:xj******************@news.indigo.ie:

Just to elaborate more on that. While this function doesn't edit any
objects; if possible I want to be able to return a non-const pointer,
as the user may want to then use it for something.


Then you should provide a non-const copy of the object in question, so
there would be no risk of blowing things up.

'const' is there to help keep programs correct. Either use it, or lose it.

--
:: bartekd / o2 pl
:: "out of confusion comes chaos -- out of chaos comes confusion and fear
:: -- then comes lunch."

Jul 22 '05 #9
JKop wrote:
Tobias Güntner posted:

template<typename CHARTYPE>
CHARTYPE* GetFirstT(CHARTYPE* p)
{
...
}

That template is non-const.


CHARTYPE can be 'char' or 'const char', depending on the parameter type.
--
Regards,
Tobias
Jul 22 '05 #10
JKop <NU**@NULL.NULL> wrote:
Here's two functions, a "const version" and a "non-const version":

char* GetFirstT(char* p)
{
for ( ; *p; ++p)
if ( *p == 't' ) return p;
return 0;
}

const char* GetFirstT(const char* p)
{
for ( ; *p; ++p)
if ( *p == 't' ) return p;
return 0;
} See how I have to define two functions, is there any handy around that?


The C standard library solves this problem with:

char *strchr(const char *ptr, char ch);

ie. using 'const' in the parameter and non-const in the return type.
This 'minimises the damage', ie. you only have to use casts
(when calling the function I mean, not when implementing it) if
you use it on a const string and assign the result to a 'const char *'.

But since this is C++ we can use a template:

template<typename Iter>
Iter GetFirstT(Iter p)
{
for ( ; ; ++p )
if (*p == 't' || *p == '\0')
return p;
}

Constraints - 'Iter' must be a type for which '++', '==' with a char,
and '*' are valid operations.

Note that I have made a slight change, it returns a pointer to the end
of the string instead of NULL if the 't' is not found. But you could
easily stick to your version, but add the constraint that 'Iter'
must be such that it can have 0 assigned to it.

There have been a couple of objections to this approach raised in
this thread, which I don't understand...

You said "the template is non-const". But it does not make sense
to say that a template is const or not, so I have no idea what you
meant. Are you unaware that you can have GetFirstT<char *> and
GetFirstT<char const *> ?

Pete Becker said "GetFirstT<wchar_t *>" doesn't work. So what?
The original stipulation was only for "char *" and "char const *",
and this example does just fine for them. There are plenty
of examples in the standard library where templates won't work
if you use the wrong types as parameters.
Jul 22 '05 #11
Tobias Güntner posted:
JKop wrote:
Tobias Güntner posted:

template<typename CHARTYPE>
CHARTYPE* GetFirstT(CHARTYPE* p)
{
...
}

That template is non-const.


CHARTYPE can be 'char' or 'const char', depending on the

parameter type.


No it cannot. CHARTYPE refers to the 'char'.

For a const template:

template<class T>
void Blah(const T)
{

}
-JKop
Jul 22 '05 #12
JKop wrote:
CHARTYPE can be 'char' or 'const char', depending on the
parameter type.


No it cannot.


Yes, it can.
What makes you think it cannot?
CHARTYPE refers to the 'char'.
CHARTYPE refers to the type the pointer points to. That can be anything,
including const chars.

For a const template:

template<class T>
void Blah(const T)


Now why would you want this one? If you pass a char* here, you have a
const pointer to non-const chars, i.e. you cannot alter the pointer.
--
Regards,
Tobias
Jul 22 '05 #13
Tobias Güntner posted:
JKop wrote:
CHARTYPE can be 'char' or 'const char', depending on the
parameter type.


No it cannot.


Yes, it can.
What makes you think it cannot?
CHARTYPE refers to the 'char'.


CHARTYPE refers to the type the pointer points to. That

can be anything, including const chars.

For a const template:

template<class T>
void Blah(const T)
Now why would you want this one? If you pass a char*

here, you have a const pointer to non-const chars, i.e. you cannot alter the pointer.


You're right.

But still I want to restrict it to either being char* or
const char*.
-JKop

Jul 22 '05 #14
JKop <NU**@NULL.NULL> wrote in message news:<i9******************@news.indigo.ie>...
Here's two functions, a "const version" and a "non-const version":
[snip - two similar implementations] const char* GetFirstT(const char* p)
{
for ( ; *p; ++p)
{
if ( *p == 't' ) return p;
}
return 0;
} char* GetFirstT(char* p)
{
return const_cast<char*>( GetFirstT(p) );
}


This is reasonable, especially if the second is inlined and the first
is not. However, it doesn't make a lot of sense that you would have a
non-const version of this particular function.

/david
Jul 22 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Dave | last post by:
Hi, I just want to share what I have found today. In the online article "Enforce Constness With C#" by Bill Wagner for "Visual Studio Magazine", he explaines how to make a little workaround to...
1
by: Richard Hayden | last post by:
Hi, I understand such pointers as 'const int* const ip' and 'const int* ip' etc., but I'm getting confused when seeing things like 'const int* const* ip' (i.e. with two or more asterisks)....
15
by: Trevor Lango | last post by:
I want to be able to cast away the constness of a private member variable in a member function of a class. I have the private data member declared as follows: const double x; I have an...
8
by: Srini | last post by:
Hello all, I was just wondering about this. A const member function guarantees constness of the object within the function body. But there's no way for a member function to guarantee the...
7
by: Olav | last post by:
Hi I wonder if it is possible to have templates expand based on constness, something like: template<typename A, typename B>copy( A &a, B &b); becoming: copy( const class AClass &a, class...
3
by: mailtogops | last post by:
Hi, I often think over the const_cast operator provided by C++ and I feel usage of const_cast or the document availale for const_cast are cumbersome. C++ provides us, const qualifier which...
14
by: PengYu.UT | last post by:
In the following program, I want an iterator contain pointer pointing to constant object not const pointer. If it is possible would you please let me know how to do it? #include...
2
by: Laurent Deniau | last post by:
I am looking for the "cleanest" way to cast away the constness of a pointee in C89, something like const_cast<T*>() in C++. Actually, I am using: #define CONST_CAST(typename,value) \ (((union {...
13
by: Javier | last post by:
Hello, I have some cuestions about constness with standard containers and pointers. Supose I have a list of pointers to some class B: std::list< B * list; I have readed that constness in...
6
by: Tarique | last post by:
Can someone please explain the idea of Logical Constness as explained in section 10.2.7.1 Of Stroustrup's "The C++ Programming Language" ,with a short working code if possible. Thank You
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.