473,386 Members | 1,736 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

C-Array iterator C++ compliance problem

Hi Everyone,
I wrote 2 functions to make a C-Style array play nice with
std::algorithms as shown:

template <typename T>
T begin(T& t)
{
return t;
}

template <typename T>
T end(T& t)
{
return (t + sizeof(t)/sizeof(t[0]));
}

Usage with a std::algorithm was easy. Thus...

const char* c_style_array[] = {"one","two","three"};

std::for_each(
begin(c_style_array),
end(c_style_array),
...do something);

Life was beautiful,

BUT...

Apparently, my compiler was not standards compliant. On moving to a
more compliant compiler my code broke.

How can I re-write my functions to make my code work again? This
non-compliance is pretty prolific through the codebase.

Thanks,
M
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Sep 28 '05 #1
12 5489
mmacrobert wrote:
I wrote 2 functions to make a C-Style array play nice with
std::algorithms as shown:

template <typename T>
T begin(T& t)
{
return t;
}

template <typename T>
T end(T& t)
{
return (t + sizeof(t)/sizeof(t[0]));
}
WHY? "C-Style arrays" decay to pointers, and pointers are iterators,
at least semantically, so they work just fine with algorithms. You
just don't need to use 'begin' or 'end'. Use 'c_style_array' and
'c_style_array + size'.
[...]


V
Sep 28 '05 #2
mmacrobert wrote:
How can I re-write my functions to make my code work again? This
non-compliance is pretty prolific through the codebase.


template < typename T, unsigned N >
T *begin ( T (&array)[N] ) { return array + 0; }

template < typename T, unsigned N >
T *end ( T (&array)[N] ) { return array + N; }

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Sep 28 '05 #3
mmacrobert wrote:
Hi Everyone,
I wrote 2 functions to make a C-Style array play nice with
std::algorithms as shown:

template <typename T>
T begin(T& t)
{
return t;
}

template <typename T>
T end(T& t)
{
return (t + sizeof(t)/sizeof(t[0]));
}

Usage with a std::algorithm was easy. Thus...

const char* c_style_array[] = {"one","two","three"};

std::for_each(
begin(c_style_array),
end(c_style_array),
...do something);

Life was beautiful,

BUT...

Apparently, my compiler was not standards compliant. On moving to a
more compliant compiler my code broke.

How can I re-write my functions to make my code work again? This
non-compliance is pretty prolific through the codebase.

Thanks,
M


Check out the implementation of boost::array:

http://boost.org/doc/html/array.html

Cheers! --M
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Sep 28 '05 #4
"mmacrobert" <mj*********@yahoo.com> writes:
I wrote 2 functions to make a C-Style array play nice with
std::algorithms as shown:

template <typename T>
T begin(T& t)
{
return t;
}

template <typename T>
T end(T& t)
{
return (t + sizeof(t)/sizeof(t[0]));
}

Usage with a std::algorithm was easy. Thus...

const char* c_style_array[] = {"one","two","three"};

std::for_each(
begin(c_style_array),
end(c_style_array),
...do something);

Life was beautiful,

BUT...

Apparently, my compiler was not standards compliant. On moving to a
more compliant compiler my code broke.

How can I re-write my functions to make my code work again? This
non-compliance is pretty prolific through the codebase.


#include <algorithm>
#include <iterator>
#include <iostream>
#include <ostream>

template <typename T, std::size_t N>
T *begin(T (&t)[N])
{
return t;
}

template <typename T, std::size_t N>
T *end(T (&t)[N])
{
return t+N;
}

int main()
{
int const numbers[] = { 0, 1, 2, 3 };
std::copy(begin(numbers),end(numbers),
std::ostream_iterator<int>(std::cout," "));
std::cout << '\n';

char const *c_style_array[] = { "one", "two", "three" };
std::copy(begin(c_style_array),end(c_style_array),
std::ostream_iterator<char const *>(std::cout," "));
std::cout << '\n';
}

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Sep 28 '05 #5

template <typename T>
T* begin(T t[])
{
return &t[0];
}

template <typename T>
const T* begin(const T t[])
{
return &t[0];
}

template <typename T, unsigned int SZ>
T* end(T (&t)[SZ])
{
return begin(t) + SZ;
}

template <typename T, unsigned int SZ>
const T* end(const T (&t)[SZ])
{
return begin(t) + SZ;
}

Regards,
Ben

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Sep 28 '05 #6

"mmacrobert" <mj*********@yahoo.com> ha scritto nel messaggio
news:11**********************@o13g2000cwo.googlegr oups.com...
Hi Everyone,
I wrote 2 functions to make a C-Style array play nice with
std::algorithms as shown:

template <typename T>
T begin(T& t)
{
return t;
}

template <typename T>
T end(T& t)
{
return (t + sizeof(t)/sizeof(t[0]));
}

Usage with a std::algorithm was easy. Thus...

const char* c_style_array[] = {"one","two","three"};

std::for_each(
begin(c_style_array),
end(c_style_array),
...do something);

Life was beautiful,

BUT...

Apparently, my compiler was not standards compliant. On moving to a
more compliant compiler my code broke.

How can I re-write my functions to make my code work again? This
non-compliance is pretty prolific through the codebase.


Try this:

template <typename T,int N>
T* begin(T (&t)[N])
{
return t;
}

template <typename T, int N>
T* end(T (&t)[N])
{
return (t + N);
}
HTH
Gianluca Silvestri
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Sep 28 '05 #7
benben wrote:
template <typename T>
T* begin(T t[])
{
return &t[0];
}

template <typename T>
const T* begin(const T t[])
{
return &t[0];
}


Isn't this entirely redundant? const X will match the
first prototype with T = "const X" and return the right
thing (a pointer to const X). The body of the function
is not doing anything different, so I don't see why the
need for the second version.

Carlos
--

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Sep 28 '05 #8
mmacrobert wrote:
I wrote 2 functions to make a C-Style array play nice with
std::algorithms as shown:

template <typename T>
T begin(T& t)
{
return t;
}

template <typename T>
T end(T& t)
{
return (t + sizeof(t)/sizeof(t[0]));
}


Actually, I cannot imagine how and why these function should have
ever worked! ... and if they worked, how they could have had the
correct semantics. However, I never had any problems with these
versions:

template <typename T, std::size_t sz>
T* begin(T (&a)[sz])
{
return a + 0;
}

template <typename T, std::size_t sz>
T* end(T (&a)[sz])
{
return a + sz;
}
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Sep 29 '05 #9
Carlos Moreno wrote:
benben wrote:
template <typename T>
T* begin(T t[])
{
return &t[0];
} template <typename T>
const T* begin(const T t[])
{
return &t[0];
}
Isn't this entirely redundant? const X will match the first
prototype with T = "const X" and return the right thing (a
pointer to const X). The body of the function is not doing
anything different, so I don't see why the need for the second
version.


Worse. A const X will result in an ambiguity, since either
function can be used, and is an equally good match.

In practice, I have used compilers which required the const
version, and compilers which didn't accept it, declaring
ambiguity. (And compilers which didn't care, and worked with or
without the const version.) All recent compilers, however, seem
to accept the code without the const versions.

--
James Kanze GABI Software
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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Sep 29 '05 #10
Isn't this entirely redundant? const X will match the
first prototype with T = "const X" and return the right
thing (a pointer to const X). The body of the function
is not doing anything different, so I don't see why the
need for the second version.

Carlos


You are correct. Its just my habit of providing const versions so i might be
planning to retrofit some idea to any of the versions.

Ben

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Oct 1 '05 #11
kanze wrote:
template <typename T>
T* begin(T t[])
{
return &t[0];
}
template <typename T>
const T* begin(const T t[])
{
return &t[0];
}


Isn't this entirely redundant? const X will match the first
prototype with T = "const X" and return the right thing (a
pointer to const X). The body of the function is not doing
anything different, so I don't see why the need for the second
version.

Worse. A const X will result in an ambiguity, since either
function can be used, and is an equally good match.


Huh? What about partial specialization rules? Something
that matches "const T" matches also T, but something that
matches T does not necessarily match const T -- if const T
is a "most specialized" match, then it should be chosen.

Am I missing something?

Carlos
--

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Oct 1 '05 #12
Carlos Moreno wrote:
kanze wrote:
template <typename T>
T* begin(T t[])
{
return &t[0];
} template <typename T>
const T* begin(const T t[])
{
return &t[0];
} Isn't this entirely redundant? const X will match the first
prototype with T = "const X" and return the right thing (a
pointer to const X). The body of the function is not doing
anything different, so I don't see why the need for the
second version.
Worse. A const X will result in an ambiguity, since either
function can be used, and is an equally good match.

Huh? What about partial specialization rules? Something that
matches "const T" matches also T, but something that matches T
does not necessarily match const T -- if const T is a "most
specialized" match, then it should be chosen. Am I missing something?


Or I am. I thought that partial specialization only applied to
classes.

I did think that there was some sort of ordering on
specializations over functions, that might apply here, but I
didn't find it immediately, and it didn't seem worth searching
further. The fact is that some compilers I have used did
declare it ambiguous. Which means that regardless of what the
standard actually says...

Of course, some compilers also required it. Which made life
pretty difficult for a while. All I can say is that I currently
don't use the extra declarations, and that the code passes the
compilers I am currently using (Sun CC 5.1, and some later
version, and g++ 3.4.? up).

--
James Kanze mailto: ja*********@free.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Oct 2 '05 #13

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

Similar topics

4
by: ChaosKCW | last post by:
Hi Using Python 2.4 I am trying to procduce a generator which will return the results of dbi SQL statement using fetchmany for performance. So instead of fetching one record for each call, I...
4
by: arnuld | last post by:
i wrote a programme to create a vector of 5 elements (0 to 4), here is the code & output: #include <iostream> #include <vector> int main() { std::vector<intivec; // dynamically create a...
0
by: toton | last post by:
Hi, I have a complex design of some dynamic situation. First I am posting the design, then a few questions regarding the problem I am facing. Hope some of the experts will answer the questions....
7
by: nguyen.h.khanh | last post by:
Hi, I have this code #include <vector> #include <string> #include <iostream> using namespace std;
15
by: vivekian | last post by:
Hi, I have this following class class nodeInfo ; class childInfo { public: int relativeMeshId ;
3
by: steve | last post by:
I have the following property in one of my applications but when I do a build I get a warning saying that it is not CLS compliant. Swatch is a class defined in a separate project/dll. I get the same...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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...

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.