Re: Questions about C++0x standard
gpderetta ha scritto:
On Oct 14, 5:14 pm, Brendan <catph...@catphive.net> wrote:
I have a couple of questions about the forthcoming c++0x standard.
Why are constexpr's not allowed to be recursive (according to the
wikipedia article)? We are still allowed to do things like this
correct?
template <typename T>
constexpr sum(T x) {
return x;
}
template <typename T, typename??? Args)
constexpr sum(T x, Args??? args) {
return x + sum(args);
}
BTW, I do not see anything in the last constant expressions proposal
nor in the last standard draft that would explicitly disallow this:
struct sum_t {
constexpr sum_t() {}
template <typename T>
constexpr T operator()(T x) {
return x;
}
template<typename F, typename T, typename Args...>
constexpr T operator()(F f, T x, Args... args) {
return x + f(sum_t(), args);
}
};
template<typename T, typename Args...>
constexpr T sum(T x, Args... args) {
return sum_t()(sum_t(), x, args);
}
Which, I think, is just anonymous recursion (http://en.wikipedia.org/
wiki/Anonymous_recursion).
So in practice it seems that you can have recursive constexprs, the
standard just make them harder to use.
The case with a variable number of arguments does not need all that
machinery, mainly because while there is a sort of "recursion" there are
*no* recursive calls involved! Consider this:
template<typename T>
constexpr T sum(T x) {
return x;
}
template<typename T, typename Args...>
constexpr T sum(T x, Args... args) {
return x + sum(args...);
}
AFAIK, this code is legal according to the current working paper. That's
because, for example, sum<int, int>() does not call sum<int, int>() but
sum<int>(), which is a different function, although instantiated from
the same template.
A case with a recursive call like this:
int factorial(int n)
{
return n < 2 ? 1 : n * factorial(n - 1);
}
can't be made constexpr according to the WP and I can't find a way to
rewrite it as you suggested to make it work.
On the other way, you can have this:
template <int N>
constexpr int factorial()
{
return N < 2 ? 1 : N * factorial<N-1>();
}
also because you switched from recursive calls to recursive
instantiation of templates, which is allowed.
HTH,
Ganesh
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]