Topic: Constexpr classes" as non-type template parameters


Author: =?ISO-8859-1?Q?Pedro_Lamar=E3o?= <pedro.lamarao@gmail.com>
Date: Sat, 1 Aug 2009 11:22:32 CST
Raw View
On 31 jul, 14:58, restor <akrze...@gmail.com> wrote:

> My question is, would it not be possible to extend the non-type
> template parameters to also include user-defined literal types? If the
> floating-point values are problematic, then allow only user defined
> literals composed only of constant integral values. ratio is just two
> integers. If C++ allows one integer as a non-type parameter it could
> easily allow two. Then the multiplication or rationals would be
> reduced to operator* rather than a meta-template ratio_multiply.

Let's consider a simpler runtime_ratio class, something like this,
with your extension:

   constexpr class runtime_ratio {
   public:

     runtime_ratio (long num, long den) : _num(num), _den(den) { }

     long num () const { return _num; }
     long den () const { return _den; }

   private:
     long _num;
     long _den;
   };

If I understand you correctly, this should allow us to write:

   template <runtime_ratio R> void foo ();

and call it like this:

   foo<runtime_ratio(1,1)>();

The specification of the external name of specializations of this
template would make an interesting problem for ABI designers to solve.
The ABI must specify an encoding for values of the runtime_ratio type.
The mechanism as a whole would require the specification of encodings
for values of any constexpr type.

Take a look at this document:

   http://www.codesourcery.com/public/cxx-abi/abi.html

In Section 5.1.5 look for the definition of <template-param> and
<template-arg> and the discussion on encoding literals.

--
  P.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: restor <akrzemi1@gmail.com>
Date: Fri, 31 Jul 2009 11:58:56 CST
Raw View
Hi,

If you hear the phrase "compile-time rational arithmetic" what do you
thik of?
I imagine a "user-defined literal" class, i.e. a class with constexpr
member functions, similar to the "complex" example from constexpr
proposal. It would be used like this:

   constexpr rational milli( 1, 1000 );
   constexpr rational micro = milli * milli;
   constexpr int den = micro.denominator();

The rational arithmetic in the C++ standard is defined with more
complex means, and in the end rational numbers are not values, but
types. std::ratio is a fascinating piece of metaprogramming in itself,
but it takes the rational arithmetic away from ordinary users and
reserves them only for metaprogramming experts. A ratio in a common
sense is a number, value, and this common sense should be preserved in
C++. The rationale for constexpr feature doesn't say it explicitly,
but one of the reasons for adding it must have been for the ordinary
programmer to be able to write

   constexpr unsigned factorial( unsigned i ) {
     return (i > 1) ? factorial(i - 1) : 1;
   }

rather than

   template< unsigned I >
   struct Factorial {
     enum { val = Factorial<I - 1>::val };
   };

   template<>
   struct Factorial<1> {
     enum { val = 1 };
   };

   template<>
   struct Factorial<0> {
     enum { val = 1 };
   };

I am not even sure if I got the latter right, but you know what I
meen. Well, at least the experts know.
Ok, the factorial example is perhaps too acadaemic, but my poit is,
constexpr functions still make the function syntax availible where it
naturally belongs. The same way, std::ratio should be a "constexpr
class" (or "user-defined literal" to be more precise) to represent
constexpr values, rather than a meta-type for representing types.

The reason it is not a "constexpr class" is that the sole purpose of
std::ratio is to be a template type parameter for class templates
std::duration and std::time_point; and although C++ has non-type
template parameters, it does not allow user-defined types, not even
user-defined literals. Am I right?

My question is, would it not be possible to extend the non-type
template parameters to also include user-defined literal types? If the
floating-point values are problematic, then allow only user defined
literals composed only of constant integral values. ratio is just two
integers. If C++ allows one integer as a non-type parameter it could
easily allow two. Then the multiplication or rationals would be
reduced to operator* rather than a meta-template ratio_multiply.

Regards,
&rzej

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]