Re: declaring constant array without initializing all the elements
On Mar 4, 11:09 am, Lionel B <m...@privacy.net> wrote:
On Tue, 04 Mar 2008 00:39:50 -0800, James Kanze wrote:
On Mar 3, 4:30 pm, Lionel B <m...@privacy.net> wrote:
[...]
Now one thing you can do is
const int const_arr = [20] = { 2, 3, 6, 11, 18, ... } // you have=
to
explicitly initialize the array with the 20 elements
As I understood it, the OP explicitly required that the array elements
"... be calculated using an equation", so I suspect that this would not=
work for them.
If the equation is known at compile time, it's pretty easy
to write a program which will generate the definition of the
array, with all of its initializers. I do this a lot
(although I do remember having problems with it in one case:
the array contained a couple of million members, and the
compiler wouldn't handle it.)
I guess that would rule out template meta-programming too :-)
It depends on the context. I use template meta-programming when
it's the simplest solution to the problem. I use an external
program to generate the code when that's the simplest solution.
Typically, the difference is when the solution requires some
internal knowledge of the C++ program: types, etc. That's only
readily available from within the compiler, so template
meta-programming is called for. Evaluating expressions like
his, however, is far more easily done in a separate program.
One technique which might be made to work if the initialisation
function were simple/suitable, would be some template meta-programming
trick, where you get the compiler to perform the calculation, the
canonical example being a compile-time calculated factorial:
http://en.wikibooks.org/wiki/C%2B%2B_Programming/Template/
Template_Meta-Programming#Example:_Compile-time_Factorial
This would be total overkill, though, I suspect.
It's a nice trick for obfuscation,
There's a rather simple solution to that: it's called
"documentation".
Doing things the hard way when there is a much simpler solution
is obfuscation. Regardless of the documentation. He wants each
element initialized with 2*i*i, where i is the index. Nothing
you can do in template meta-programming will be anywhere near as
clear as:
for ( int i = 0 ; i != limit ; ++ i ) {
dest << 2*i*i << ',' ;
}
but generating the code with a separate program is a lot
easier and more readable.
Hmm... yes, if having a whole new program to maintain (and
document) counts as "a lot easier and more readable".
And your template meta-program is what, if it isn't a "whole new
program". The difference is that my new program is written in a
language designed from the start for such programs, and is
expressed simply and elegantly in a separate source file, and
not embedded somewhere in the middle of the sources for the
program it's supposed to be generating.
On the whole I think I'd prefer the const reference array
solution from your other post; I suspect that the OP might be
happy with a const lvalue for array access.
The simplest solution is probably the specialized iterators used
to initialize std::vector. Something like:
std::vector< int > v(
boost::make_transform_iterator(
boost::make_counting_iterator( 0 ), X() ),
boost::make_transform_iterator(
boost::make_counting_iterator( 10 ), X() ) ) ;
, where X is:
struct X : public std::unary_function< int, int >
{
int operator()( int i ) const { return 2*i*i ; }
} ;
(You could also write:
std::vector< int > v(
boost::make_transform_iterator(
boost::make_counting_iterator( 0 ),
boost::bind( std::multiplies< int >(), 2,
boost::bind( std::multiplies< int >(), _1,
_1 ) ) ),
boost::make_transform_iterator(
boost::make_counting_iterator( 10 ),
boost::bind( std::multiplies< int >(), 2,
boost::bind( std::multiplies< int >(), _1,
_1 ) ) ) ) ;
, without the extra class, and I suspect that boost::lambda
would work in this case as well. In the absense of a true
lambda, however, I think I'd go with the extra class.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34