From: tohava on
I am not sure if anyone thought of this or not.

Let us say we have this piece of code:

int y;
int x = 1;
for (int i = 2; i <= y; ++i) x *= i; // potentially, this can be some
initialization code for x that spans 10 lines
// from here, x should be constant, but we can't do it


One way to do this would be putting the factorial loop as a separate
function. However, I can think of another way:

int y;
const int x = ([](){ int ret = 1;
for (int i = 2; i <= y; ++i) ret *= i;
return ret; })();


In case I fumbled the syntax, what I meant to do was both to write a
lambda expression and call it in-place. Is this possible in the new
standard? Also, do you think it is useful and/or have better ideas to
solve the problem of creating a const variable with initialization
that cannot be easily expressed in a form without mutability?

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

From: SG on
On 21 Mrz., 09:08, tohava <toh...(a)gmail.com> wrote:
> I am not sure if anyone thought of this or not.
>
> Let us say we have this piece of code:
>
> int y;
> int x = 1;
> for (int i = 2; i <= y; ++i) x *= i; // potentially, this can be
> // some initialization code for x that spans 10 lines
> // from here, x should be constant, but we can't do it

You mean, you want x to be a /constant expression/ ?

> One way to do this would be putting the factorial loop as a
> separate function. However, I can think of another way:
>
> int y;
> const int x = ([](){ int ret = 1;
> for (int i = 2; i <= y; ++i) ret *= i;
> return ret; })();
>
> In case I fumbled the syntax, what I meant to do was both to write
> a lambda expression and call it in-place.

The lambda's return type is missing. You also need to put something
into the capture clause about how to capture y.

int y = 12;
const int x = ([&]()->int{
int ret = 1;
for (int i=2; i<=y; ++i) ret*=i;
return i;
})();

But that doesn't make x a constant expression. If you replace "const"
with "constexpr" the code won't compile because "constexpr" requires
the initializer to be a constant expression and this initializer here
is not.

> Also, do you think it is useful and/or have better ideas
> to solve the problem of creating a const variable with
> initialization that cannot be easily expressed in a form without
> mutability?

Yes, this should work:

constexpr int fak(int x) {
return (x<=1) ? 1 : x*fak(x-1);
}

void foo() {
constexpr int x = fak(3);
double array[x];
}

as well as the "old school metaprogramming":

template<int X> struct fak {
static const int value = X*fak<(X-1)>::value;
};
template<> struct fak<0> {
static const int value = 1;
};

void foo() {
constexpr int x = fak<3>::value;
double array[x];
}

Cheers,
SG


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

From: Daniel Krügler on
On 21 Mrz., 09:08, tohava <toh...(a)gmail.com> wrote:
> I am not sure if anyone thought of this or not.
>
> Let us say we have this piece of code:
>
> int y;
> int x = 1;
> for (int i = 2; i <= y; ++i) x *= i; // potentially, this can be some
> initialization code for x that spans 10 lines
> // from here, x should be constant, but we can't do it
>
> One way to do this would be putting the factorial loop as a separate
> function. However, I can think of another way:
>
> int y;
> const int x = ([](){ int ret = 1;
> for (int i = 2; i <= y; ++i) ret *= i;
> return ret; })();
>
> In case I fumbled the syntax, what I meant to do was both to write a
> lambda expression and call it in-place. Is this possible in the new
> standard? Also, do you think it is useful and/or have better ideas to
> solve the problem of creating a const variable with initialization
> that cannot be easily expressed in a form without mutability?

Sebastian is right regarding his comments related to
constant expression, but if I understand your idea
correctly, you have found an approach how to define
a normal const variable without an additional helper
function or class - looks nice indeed, if you don't
need to support constant expressions!

Greetings from Bremen,

Daniel Kr�gler


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

From: Mathias Gaunard on
On 21 mar, 08:08, tohava <toh...(a)gmail.com> wrote:
> I am not sure if anyone thought of this or not.
>
> Let us say we have this piece of code:
>
> int y;
> int x = 1;
> for (int i = 2; i <= y; ++i) x *= i; // potentially, this can be some
> initialization code for x that spans 10 lines
> // from here, x should be constant, but we can't do it

Use std::accumulate.

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