 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
dmitry.sychov@mail.ru Guest
|
Posted: Thu Sep 07, 2006 11:29 pm Post subject: SOLUTION: compile time array size using type only |
|
|
Hi
here is the way for finding array size using type only
////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };
int length = cx_array_length<char[3]>::value;
//////////
the question is: is the compiler is smart enough not to put "_arr" into
the compiled object?
if you have better solutions/any ideas please share
regards, dmitry
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Fri Sep 08, 2006 4:55 am Post subject: Re: SOLUTION: compile time array size using type only |
|
|
"dmitry.sychov (AT) mail (DOT) ru" <dmitry.sychov (AT) mail (DOT) ru> writes:
| Quote: | here is the way for finding array size using type only
////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };
int length = cx_array_length<char[3]>::value;
//////////
the question is: is the compiler is smart enough not to put "_arr"
into the compiled object?
if you have better solutions/any ideas please share
|
What about:
template <typename T>
class cx_array_length
{
enum
{
value = 1
};
};
template <typename T, unsigned N>
struct cx_array_length<T[N]>
{
enum
{
value = N
};
};
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Alf P. Steinbach Guest
|
Posted: Fri Sep 08, 2006 4:57 am Post subject: Re: SOLUTION: compile time array size using type only |
|
|
* dmitry.sychov (AT) mail (DOT) ru:
| Quote: |
here is the way for finding array size using type only
////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
|
It would be a good idea to use std::size_t instead of unsigned here.
Also, 'inline' is superfluous.
| Quote: | (&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };
int length = cx_array_length<char[3]>::value;
//////////
the question is: is the compiler is smart enough not to put "_arr" into
the compiled object?
|
The number of tails a dog has depends on the dog, and is not mentioned
in the Holy Standard. ;-)
| Quote: | if you have better solutions/any ideas please share
|
template< typename T > T const& aCompileTimeValueOf(); // No impl.
typedef SomeType X[1234];
std::size_t const length = N_ELEMENTS( aCompileTimeValueOf<X>() );
where N_ELEMENTS is any strictly compile time argument evaluation
number-of-elements-in-array macro.
Since you addressed the "using type only" aspect you're probably aware
of the techniques available when you have an actual array instance at
hand, i.e. how N_ELEMENTS could be implemented, but for those who aren't
familiar with this, see <url:
http://home.no.net/dubjai/win32cpptut/special/pointers/array_size.doc.pdf>
(which perhaps should be updated with Dmitry's technique/aspect).
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
lhyatt@princeton.edu Guest
|
Posted: Fri Sep 08, 2006 5:03 am Post subject: Re: SOLUTION: compile time array size using type only |
|
|
dmitry.sychov (AT) mail (DOT) ru wrote:
| Quote: | Hi
here is the way for finding array size using type only
////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };
int length = cx_array_length<char[3]>::value;
//////////
the question is: is the compiler is smart enough not to put "_arr" into
the compiled object?
|
Since _arr is a static member, you are going to need to declare it in a
translation unit somewhere, and space will be allocated for it once,
which isn't such a big deal.
| Quote: | if you have better solutions/any ideas please share
|
you can use the size of an array as a template parameter, so you could
do this much more directly with partial specialization, like this:
//define a general template for non-array types
template<typename InvalidType>
struct array_length {
enum {value=0};
//could also force a compile-time error here, with
BOOST_STATIC_ASSERT
};
//specialize it for array types
template<typename T, std::size_t N>
struct array_length<T[N]> {
enum {value=N};
};
Now you have eg array_length<char[3]>::value = 3 as a compile time
constant.
-lewis
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Guest
|
Posted: Fri Sep 08, 2006 9:12 pm Post subject: Re: SOLUTION: compile time array size using type only |
|
|
dmitry.sychov (AT) mail (DOT) ru wrote:
| Quote: | Hi
here is the way for finding array size using type only
////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };
int length = cx_array_length<char[3]>::value;
//////////
the question is: is the compiler is smart enough not to put "_arr" into
the compiled object?
|
You don't need _arr - just cast 0 into a T * or T & - it is not
evaluated inside the sizeof. Some may argue that technically it
invokes undef behaviour, I'm not sure, but this is not a case where I'd
be concerned.
| Quote: | if you have better solutions/any ideas please share
|
Thomas Maeder's looks better to me. Quite elegant. I only mention the
above stuff in case it helps elsewhere.
Tony
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Fri Sep 08, 2006 9:19 pm Post subject: Re: SOLUTION: compile time array size using type only |
|
|
Thomas Maeder wrote:
| Quote: | "dmitry.sychov (AT) mail (DOT) ru" <dmitry.sychov (AT) mail (DOT) ru> writes:
here is the way for finding array size using type only
////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };
int length = cx_array_length<char[3]>::value;
//////////
the question is: is the compiler is smart enough not to put
"_arr" into the compiled object?
|
If I understand the standard correctly, it isn't allowed to
instantiate the definition (and couldn't if it was, since you
haven't provided a definition) unless you use it.
| Quote: | if you have better solutions/any ideas please share
What about:
template <typename T
class cx_array_length
{
enum
{
value = 1
};
};
template <typename T, unsigned N
struct cx_array_length<T[N]
{
enum
{
value = N
};
};
|
But what's the point. In both cases, in order to instantiate
the template, you have to specify the type, to specify the type,
you have to specify the size literally, and if you know the
size, it's much easier to write just:
int length = 3 ;
than
int length = cx_array_length< int[ 3 ] >::value ;
Or is there something here that I've missed?
We (you and I) recently did something more useful in
de.comp.lang.iso-c++, if I recall correctly:
template< typename N, size_t N >
char (&array_size( T (&array)[ N ] ))[ N ] ;
which allows writing things like:
double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = sizeof( array_size( someArray ) ) ;
Obviously, the problem is even easier if you don't require a
constant integral expression.
--
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! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Fri Sep 08, 2006 9:20 pm Post subject: Re: SOLUTION: compile time array size using type only |
|
|
lhyatt (AT) princeton (DOT) edu wrote:
| Quote: | dmitry.sychov (AT) mail (DOT) ru wrote:
here is the way for finding array size using type only
////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };
int length = cx_array_length<char[3]>::value;
//////////
the question is: is the compiler is smart enough not to put
"_arr" into the compiled object?
Since _arr is a static member, you are going to need to
declare it in a translation unit somewhere, and space will be
allocated for it once, which isn't such a big deal.
|
Only if it is actually instantiated (the static member, not the
class). And it should only be instatiated if it is actually
used, which it isn't.
--
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! ] |
|
| Back to top |
|
 |
Guest
|
Posted: Tue Sep 12, 2006 6:47 am Post subject: Re: SOLUTION: compile time array size using type only |
|
|
kanze wrote:
| Quote: |
But what's the point. In both cases, in order to instantiate
the template, you have to specify the type, to specify the type,
you have to specify the size literally, and if you know the
size, it's much easier to write just:
int length = 3 ;
than
int length = cx_array_length< int[ 3 ] >::value ;
Or is there something here that I've missed?
|
I was wondering the same thing, but I suspect there may be times when
'int[3]' is only known as T - ie maybe this helps in other template
code?
Tony
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
John Moeller Guest
|
Posted: Wed Sep 13, 2006 4:44 am Post subject: Re: SOLUTION: compile time array size using type only |
|
|
kanze wrote:
,,,
| Quote: | template< typename N, size_t N
char (&array_size( T (&array)[ N ] ))[ N ] ;
which allows writing things like:
double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = sizeof( array_size( someArray ) ) ;
.... |
As an aside, I'm curious; could you not just have easily written:
template< typename T, size_t N >
size_t array_size( T (& array)[ N ] ) { return N; }
so that you could have written:
double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = array_size( someArray ) ;
thus directly obtaining the array size, rather than using sizeof? I
have to assume there's a reason that I'm missing. Either way, I think
that the technique is great; I'll have to remember it for future use.
John Moeller
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Hendrik Schober Guest
|
Posted: Wed Sep 13, 2006 8:53 pm Post subject: Re: SOLUTION: compile time array size using type only |
|
|
John Moeller <fishcorn (AT) gmail (DOT) com> wrote:
| Quote: | kanze wrote:
,,,
template< typename N, size_t N
char (&array_size( T (&array)[ N ] ))[ N ] ;
which allows writing things like:
double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = sizeof( array_size( someArray ) ) ;
...
As an aside, I'm curious; could you not just have easily written:
template< typename T, size_t N
size_t array_size( T (& array)[ N ] ) { return N; }
so that you could have written:
double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = array_size( someArray ) ;
thus directly obtaining the array size, rather than using sizeof? I
have to assume there's a reason that I'm missing. [...]
|
Yours is a run-time solution, James' yields a compile-time
constant.
Schobi
--
SpamTrap (AT) gmx (DOT) de is never read
I'm Schobi at suespammers dot org
"The sarcasm is mightier than the sword."
Eric Jarvis
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Sep 13, 2006 8:54 pm Post subject: Re: SOLUTION: compile time array size using type only |
|
|
John Moeller wrote:
| Quote: | kanze wrote:
template< typename N, size_t N
char (&array_size( T (&array)[ N ] ))[ N ] ;
which allows writing things like:
double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = sizeof( array_size( someArray ) ) ;
...
As an aside, I'm curious; could you not just have easily written:
template< typename T, size_t N
size_t array_size( T (& array)[ N ] ) { return N; }
so that you could have written:
double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = array_size( someArray ) ;
thus directly obtaining the array size, rather than using sizeof?
|
In this case, yes, and in fact, that is the way it is done in my
own library. The solution above came about as a result of a
discussion in de.comp.lang.iso_c++, where it was also desired to
be able to do something like:
double secondArray[ sizeof( array_size( firstArray ) ) ] ;
That's what I meant when I said: "Obviously, the problem is even
easier if you don't require a constant integral expression."
(Unless I'm using static initialization, or the initialization
list is being used to determine the size, my arrays are always
std::vector. Which means that I don't need a constant integral
expression. So my code uses the simple forms:
template< typename T, size_t N >
size_t
size( T (&array)[ N ] )
{
return N ;
}
and the equivalent for begin() and end(). The names of the
functions being chosen, of course, to correspond to those of the
member functions in an STL container.)
--
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! ] |
|
| Back to top |
|
 |
Gennaro Prota Guest
|
Posted: Wed Sep 13, 2006 11:40 pm Post subject: Re: SOLUTION: compile time array size using type only |
|
|
On 13 Sep 2006 11:54:44 -0400, "kanze" <kanze@gabi-soft.fr> wrote:
| Quote: | In this case, yes, and in fact, that is the way it is done in my
own library. The solution above came about as a result of a
discussion in de.comp.lang.iso_c++, where it was also desired to
be able to do something like:
double secondArray[ sizeof( array_size( firstArray ) ) ] ;
|
I don't doubt that you independently reinvented it, however I first
saw that tecnique in code by Dietmar Kuehl. IIRC it was code written
before year 2000.
I wrote a generalized version for multidimensional arrays which was
available in the boost vault. I plan to make an even more general
version, supporting tr1::array (and thus size==0), available under the
GPL. Of course the plain function is enough for most purposes. And
generalized constant expressions proposed by B. Stroustrup & G. Dos
Reis would give the best of both worlds.
--
Gennaro Prota
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Thu Sep 14, 2006 5:10 pm Post subject: Re: SOLUTION: compile time array size using type only |
|
|
Gennaro Prota wrote:
| Quote: | On 13 Sep 2006 11:54:44 -0400, "kanze" <kanze@gabi-soft.fr> wrote:
In this case, yes, and in fact, that is the way it is done in
my own library. The solution above came about as a result of
a discussion in de.comp.lang.iso_c++, where it was also
desired to be able to do something like:
double secondArray[ sizeof( array_size( firstArray ) ) ] ;
I don't doubt that you independently reinvented it, however I
first saw that tecnique in code by Dietmar Kuehl. IIRC it was
code written before year 2000.
|
It wouldn't surprise me. I don't claim to have "invented" it.
I do think that anyone familiar with template meta-programming
today, even in it's simplest forms, would come up with it, given
the normal begin(), end() and size() functions (which I didn't
invent either, but heard about somewhere, although I don't
remember where). It wouldn't surprise me either that Dietmar
invented it before 2000, when it wouldn't have been at all
evident; he's one of the most gifted programmers I know.
I mentionned the discussion in de.comp.lang.iso_c++ only because
I was responding to Thomas Maeder, who had mentionned it there
not more than a week ago.
--
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! ] |
|
| Back to top |
|
 |
Adrian Guest
|
Posted: Sun Sep 17, 2006 3:58 pm Post subject: Re: SOLUTION: compile time array size using type only |
|
|
John Moeller wrote:
| Quote: | As an aside, I'm curious; could you not just have easily written:
template< typename T, size_t N
size_t array_size( T (& array)[ N ] ) { return N; }
so that you could have written:
double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = array_size( someArray ) ;
|
Can someone explain how that works? I can't work out how the value
for template parameter N is determined when all you pass to the
array_size function is the array ptr.
Thanks
Adrian.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Bob Guest
|
Posted: Mon Sep 18, 2006 12:06 am Post subject: Re: SOLUTION: compile time array size using type only |
|
|
Adrian wrote:
| Quote: |
John Moeller wrote:
As an aside, I'm curious; could you not just have easily written:
template< typename T, size_t N
size_t array_size( T (& array)[ N ] ) { return N; }
so that you could have written:
double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = array_size( someArray ) ;
Can someone explain how that works? I can't work out how the value
for template parameter N is determined when all you pass to the
array_size function is the array ptr.
|
You're not. The function is being passed a reference to an array of
size N.
Of course, this assumes that the compiler has enough information, within
the scope where the function is called, to know it is working with an
array. The following would result in an error;
size_t intermediary(double *v)
{
return array_size(v);
}
int main()
{
double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
size_t length = intermediary(someArray);
}
as the only information available to the compiler, at the point where
array_size() is called, is a pointer which includes no size information.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|