Topic: pair, tuple and constexpr


Author: gdr@cs.tamu.edu (Gabriel Dos Reis)
Date: Wed, 21 Nov 2007 17:54:34 GMT
Raw View
  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

--8323584-1474595675-1195666386=:6642
Content-Type: TEXT/PLAIN; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Sun, 18 Nov 2007, Daniel Kr=C3=BCgler wrote:

| I totally agree. Another unfortunate result of the current rules
| is that it will be impossible to define concepts with associated
| functions that are constexpr functions, because a concept_map
| requires binding to reference arguments.=20

Maybe the real problem is that concept_maps should not require
references where there is no need to refer to memory.

| Currently I'm not sure
| whether this an unnecessary restriction of concept_map rules
| or constexpr rules.

we haven't established that in the case of constexpr, it is an
unnecessary restriction.  Any constructive, logically coherent,
suggestion to make the semantics more widely applicable is obviously
welcome -- assuming the committee has resource left.  Please notice
that trying to optimize out memory references and writing standardese
for that are both very tricky businesses -- just look at the DRs and
how often confusion about const static data members of integral types
come up.  The standard text had to be revised about the very notion of
`use'.  I don't know whether it is clearer now, but for sure it needed
to be re-evaluated.  There is some value to value semantics: it is
simpler to explain and to specify :-)

--=20
Dr. Gabriel Dos Reis (gdr@cs.tamu.edu), Assistant Professor
       http://www.cs.tamu.edu/people/faculty/gdr
 Texas A&M University -- Department of Computer Science
 301, Bright Building -- College Station, TX 77843-3112
--8323584-1474595675-1195666386=:6642--

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





Author: "=?ISO-8859-1?Q?Daniel_Kr=FCgler?=" <daniel.kruegler@googlemail.com>
Date: Wed, 21 Nov 2007 15:00:20 CST
Raw View
On 21 Nov., 18:54, g...@cs.tamu.edu (Gabriel Dos Reis) wrote:
> On Sun, 18 Nov 2007, Daniel Kr   gler wrote:
> Maybe the real problem is that concept_maps should not require
> references where there is no need to refer to memory.

That would indeed be an absolute satisfactory solution and
I asked Doug Gregor exactly this question. If you consider
this as an probably feasible approach, there a good chances
that it might work for todays compiler technology.

> we haven't established that in the case of constexpr, it is an
> unnecessary restriction.  Any constructive, logically coherent,
> suggestion to make the semantics more widely applicable is obviously
> welcome -- assuming the committee has resource left.  Please notice
> that trying to optimize out memory references and writing standardese
> for that are both very tricky businesses -- just look at the DRs and
> how often confusion about const static data members of integral types
> come up.  The standard text had to be revised about the very notion of
> `use'.  I don't know whether it is clearer now, but for sure it needed
> to be re-evaluated.  There is some value to value semantics: it is
> simpler to explain and to specify :-)

I understand the resource limitations and I would like to
thank everyone from the committee members for their
great work done. Although I never participated such meetings,
I regularily read the public available papers and I think that
I can rather good estimate the blood and sweat contained
in them.
Yes, I agree that the value approach has several advantages
(and that it brought the std algorithms to their currently known
state of an efficient beast), but it would be nice, if the per-value-
*requirement* of constexpr functions could be lifted *and*
the reference-*requirement* of concept_maps as well.

Just out of interest I would like to draw a connection to
function inlining: Is anyone aware of empirical data that
shows that inline-declared functions with reference arguments
are rarely inlined than those with value arguments? (My
assumption is that Thorsten Ottosen's reasoning went
into this direction, but I might err).

Greetings from Bremen,

Daniel Kr   gler







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





Author: gdr@cs.tamu.edu (Gabriel Dos Reis)
Date: Mon, 26 Nov 2007 17:34:14 GMT
Raw View
  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

--8323584-720282558-1195707029=:9901
Content-Type: TEXT/PLAIN; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wed, 21 Nov 2007, Daniel Kr=C3=BCgler wrote:

| On 21 Nov., 18:54, g...@cs.tamu.edu (Gabriel Dos Reis) wrote:
| > On Sun, 18 Nov 2007, Daniel Kr=C3=BCgler wrote:
| > Maybe the real problem is that concept_maps should not require
| > references where there is no need to refer to memory.
|=20
| That would indeed be an absolute satisfactory solution and
| I asked Doug Gregor exactly this question. If you consider
| this as an probably feasible approach, there a good chances
| that it might work for todays compiler technology.

that is a "known issue" regularly discussed in the past by people
involved in the design of concepts for C++.

[...]

| Just out of interest I would like to draw a connection to
| function inlining: Is anyone aware of empirical data that
| shows that inline-declared functions with reference arguments
| are rarely inlined than those with value arguments? (My
| assumption is that Thorsten Ottosen's reasoning went
| into this direction, but I might err).

I've seen cases in the past, when I was more actively concerned by
GCC's inlining strategies.  Alas, I've not kept links to public data;
but I'm sure people will post data in either directions.  The
majority I've seen were in favor of call-by-value.

Note however that the semantics of the language must be designed
independently of whatever optimization techniques are applied by the
compiler for a given translation unit.  So, we cannot count on the
fact that -On optimization level gives license to the compiler
to transmute the calling convention from FOO to BAR, and vice versa
-- given C++'s separate compilation model inherited from C.
Similarly, throwing in constant folding through const references is
very tricky to specify -- and to implement correctly.

--=20
Dr. Gabriel Dos Reis (gdr@cs.tamu.edu), Assistant Professor
       http://www.cs.tamu.edu/people/faculty/gdr
 Texas A&M University -- Department of Computer Science
 301, Bright Building -- College Station, TX 77843-3112
--8323584-720282558-1195707029=:9901--

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





Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Tue, 13 Nov 2007 11:01:16 CST
Raw View
On Nov 12, 10:22 pm, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
wrote:
> template <class T>
> struct call_traits
> {
>   typedef typename conditional<
>     is_literal<T>,

Daniel-the-nit-picker:

is_literal<T>::value,

(Yes, this is a slight asymmetry relative to the boost naming
convention)

>     T,
>     typename add_lvalue_reference<
>       typename add_const<T>::type
>       >::type
>     >::type type;
>
> };
>
> template <class T1, class T2>
> struct pair
> {
>   T1 first;
>   T2 second;
>
>   constexpr pair(
>     typename call_traits<T1>::type a,
>     typename call_traits<T2>::type b)
>     : first(a), second(b)
>   {}
>
>   /* etc. */
>
> };

Yes, good idea! I even think that the templated c'tor can be
implemented, but in this case we cannot use call_traits and
must instead two (aaarrg, 4) mutually exclusive c'tor variants
(via concepts or SFINAE), because of the otherwise impossible
argument deductivity (Resolve T given call_traits<T>::type).

I don't want to conceal one downer of std::is_literal: Actually a such
nominated literal type is just an optimistic categorization and
not binding, because a literal type can *also* have non-constexpr
c'tors. If we consider this example

struct Literal {
  constexpr Literal(int);
  Literal(const std::string&);
};

std::pair<Literal, int> p(Literal("no literal"), 42);

this would invoke the c'tor taking arguments by value (because
Literal itself is a literal type), although the correspondingly
called c'tor of std::pair cannot be a constexpr c'tor due to the
non-constexpr-compatible argument of type Literal. Does this
harm? Probably not, but it depends on the resolution of
what you mention here:

> Of course, this definition assumes that constexpr is silently ignored if
> either T1 or T2 is not a literal type (see discussion in thread "Defect
> report: [dcl.constexpr]/5 constexpr and templates").

Greetings from Bremen,

Daniel


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





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Tue, 13 Nov 2007 22:40:00 GMT
Raw View
Daniel Kr=C3=BCgler ha scritto:
> On Nov 12, 10:22 pm, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
> wrote:
>>
>> template <class T1, class T2>
>> struct pair
>> {
>>   T1 first;
>>   T2 second;
>>
>>   constexpr pair(
>>     typename call_traits<T1>::type a,
>>     typename call_traits<T2>::type b)
>>     : first(a), second(b)
>>   {}
>>
>>   /* etc. */
>>
>> };
>=20
> Yes, good idea! I even think that the templated c'tor can be
> implemented, but in this case we cannot use call_traits and
> must instead two (aaarrg, 4) mutually exclusive c'tor variants
> (via concepts or SFINAE), because of the otherwise impossible
> argument deductivity (Resolve T given call_traits<T>::type).

I don't get it. This constructor is not a template, so argument
deduction is never performed on it... (at least not unless N2332 is
approved)

> I don't want to conceal one downer of std::is_literal: Actually a such
> nominated literal type is just an optimistic categorization and
> not binding, because a literal type can *also* have non-constexpr
> c'tors. If we consider this example
>=20
> struct Literal {
>   constexpr Literal(int);
>   Literal(const std::string&);
> };
>=20
> std::pair<Literal, int> p(Literal("no literal"), 42);
>=20
> this would invoke the c'tor taking arguments by value (because
> Literal itself is a literal type), although the correspondingly
> called c'tor of std::pair cannot be a constexpr c'tor due to the
> non-constexpr-compatible argument of type Literal.

Being a "literal type" is a trait of the type, not of a single instance.
If an instance L of class Literal is constructed with a non-constexpr
constructor, then L is not a constant expression but it still has
"literal type".

> non-constexpr-compatible argument of type Literal. Does this
> harm? Probably not, but it depends on the resolution of
> what you mention here:
>=20
>> Of course, this definition assumes that constexpr is silently ignored =
if
>> either T1 or T2 is not a literal type (see discussion in thread "Defec=
t
>> report: [dcl.constexpr]/5 constexpr and templates").
>=20

No, this it totally unrelated. A constexpr function does not cease to be
constexpr simply because it's called with an argument that is not a
constant expression. The problem I was referring to is the following:
consider the function

  constexpr void f(T t);

if T is not of literal type then the declaration of f() is ill-formed.
However if it's template:

  template <class T>
  constexpr void f(T t);

when f<>() is specialized with a T which is not a literal type then
constexpr is silently ignored (see 7.1.5/5). The problem I raised is
that the wording in 7.1.5/5 refers to template functions only and the
discussion is about whether it applies or not (or doesn't apply but
should) to member functions of a class template and member templates.

Cheers,

Ganesh

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





Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Wed, 14 Nov 2007 13:02:40 CST
Raw View
On Nov 13, 11:40 pm, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
wrote:
> Daniel Kr   gler ha scritto:
> > Yes, good idea! I even think that the templated c'tor can be
> > implemented, but in this case we cannot use call_traits and
> > must instead two (aaarrg, 4) mutually exclusive c'tor variants
> > (via concepts or SFINAE), because of the otherwise impossible
> > argument deductivity (Resolve T given call_traits<T>::type).
>
> I don't get it. This constructor is not a template, so argument
> deduction is never performed on it... (at least not unless N2332 is
> approved)

This is a misunderstanding. I was already one step further and
considered to make

template<class U, class V> pair(U&& x, V&& y);

constexpr-aware. In this case the compiler has to deduce U and V
and we could not apply the call_traits.

> Being a "literal type" is a trait of the type, not of a single instance.
> If an instance L of class Literal is constructed with a non-constexpr
> constructor, then L is not a constant expression but it still has
> "literal type".

Totally agreed. I was only considering whether the fact that a
given literal type can be once used in constant expressions
and once not (e.g. because I used once a constexpr c'tor and
once not) would have negative impact on the performance in
above described scenarios. My current result of my "loud
thinking" is that it would not harm, because the bytes are
still the same.

> >> Of course, this definition assumes that constexpr is silently ignored if
> >> either T1 or T2 is not a literal type (see discussion in thread "Defect
> >> report: [dcl.constexpr]/5 constexpr and templates").
>
> No, this it totally unrelated. A constexpr function does not cease to be
> constexpr simply because it's called with an argument that is not a
> constant expression. The problem I was referring to is the following:
> consider the function
>
>   constexpr void f(T t);
>
> if T is not of literal type then the declaration of f() is ill-formed.
> However if it's template:
>
>   template <class T>
>   constexpr void f(T t);
>
> when f<>() is specialized with a T which is not a literal type then
> constexpr is silently ignored (see 7.1.5/5). The problem I raised is
> that the wording in 7.1.5/5 refers to template functions only and the
> discussion is about whether it applies or not (or doesn't apply but
> should) to member functions of a class template and member templates.

Yes, you are right, I was a little bit hasty here ;-)

Greetings from Bremen,

Daniel


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





Author: Alberto Ganesh Barbati <AlbertoBarbati@libero.it>
Date: Wed, 14 Nov 2007 18:17:25 CST
Raw View
Daniel Kr  gler ha scritto:
>
> This is a misunderstanding. I was already one step further and
> considered to make
>
> template<class U, class V> pair(U&& x, V&& y);
>
> constexpr-aware. In this case the compiler has to deduce U and V
> and we could not apply the call_traits.
>

Unfortunately, in order to be constexpr, all function's arguments must
be of literal type. References (lvalue or rvalue, it doesn't matter) are
not literal types, so the above constructor can never be constexpr.

Ganesh

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





Author: "=?ISO-8859-1?Q?Daniel_Kr=FCgler?=" <daniel.kruegler@googlemail.com>
Date: Thu, 15 Nov 2007 11:06:27 CST
Raw View
On Nov 15, 1:17 am, Alberto Ganesh Barbati <AlbertoBarb...@libero.it>
wrote:
> Daniel Kr   gler ha scritto:
> > This is a misunderstanding. I was already one step further and
> > considered to make
>
> > template<class U, class V> pair(U&& x, V&& y);
>
> > constexpr-aware. In this case the compiler has to deduce U and V
> > and we could not apply the call_traits.
>
> Unfortunately, in order to be constexpr, all function's arguments must
> be of literal type. References (lvalue or rvalue, it doesn't matter) are
> not literal types, so the above constructor can never be constexpr.

That is correct and this would have the effect that two mutually
exclusive templated c'tors are sufficient.

I'm just in the process to communicate with the authors of N2421,
because the combination of current rules concerning signatures in
concept maps with those constraints on constexpr functions make it
AFAIS basically impossible to declare an associated function as
constexpr function. This has the effect that concept checks would
need to reject code which is ok from the standpoint of the remaining
language rules. If nothing helps, late_check would come into the
game, but I would really like to minimize it's usage...

Greetings from Bremen,

Daniel


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





Author: Thorsten Ottosen <thorsten.ottosen@dezide.com>
Date: Sun, 18 Nov 2007 09:29:52 CST
Raw View
Daniel Kr  gler skrev:
> On Nov 12, 1:59 am, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
> wrote:
>> Let's rephrase my question, then: would it make sense to modify the
>> current definition of pair and/or tuple so that they could be literal
>> types whenever all the template arguments are of literal type? For
>> example, the current std::pair constructor could be defined as
>>
>> constexpr pair(/implementation defined/ x, /implementation defined/ y);
>>
>> where the type of x is T1 if T1 is a literal type or const T1&
>> otherwise, and similarly for T2. (Notice that this kind of
>> "implementation defined" signature is already being used in the
>> standard, see for example the constructor of unique_ptr).
>
> Personally I think this is a good reason, see e.g. my use-case
> of a function template abs both useful in constant expressions
> and otherwise, the branch based on an hypothetical std::is_literal,
> see
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#719

The use case seems very fair, but IMO the language rules for constexpr
are *very* unfortunate, effectively creating another code-duplication
problem.

A *good* compiler, when it sees,

template< class T >
void foo( const T& t );

generates different parameter passing code depending on the type T.
That begs the question of why that is not also possible for a constexpr
constructor/function.

We should strive to avoid manuall code duplication.

-Thorsten

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





Author: "=?ISO-8859-1?Q?Daniel_Kr=FCgler?=" <daniel.kruegler@googlemail.com>
Date: Sun, 18 Nov 2007 15:41:36 CST
Raw View
On 18 Nov., 16:29, Thorsten Ottosen <thorsten.otto...@dezide.com>
wrote:
> The use case seems very fair, but IMO the language rules for constexpr
> are *very* unfortunate, effectively creating another code-duplication
> problem.
>
> A *good* compiler, when it sees,
>
> template< class T >
> void foo( const T& t );
>
> generates different parameter passing code depending on the type T.
> That begs the question of why that is not also possible for a constexpr
> constructor/function.
>
> We should strive to avoid manuall code duplication.

I totally agree. Another unfortunate result of the current rules
is that it will be impossible to define concepts with associated
functions that are constexpr functions, because a concept_map
requires binding to reference arguments. Currently I'm not sure
whether this an unnecessary restriction of concept_map rules
or constexpr rules.

Greetings from Bremen,

Daniel Kr   gler




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





Author: gdr@cs.tamu.edu (Gabriel Dos Reis)
Date: Mon, 19 Nov 2007 18:19:36 GMT
Raw View
On Sun, 18 Nov 2007, Thorsten Ottosen wrote:

| A *good* compiler, when it sees,
|
| template< class T >
| void foo( const T& t );
|
| generates different parameter passing code depending on the type T.

None of my compilers do, so I suspect, by your criteria, they are not
good.  Please would you recommend -- by names -- some of those good
compilers you use for your everyday programming job?  Thanks.

--
Dr. Gabriel Dos Reis (gdr@cs.tamu.edu), Assistant Professor
       http://www.cs.tamu.edu/people/faculty/gdr
 Texas A&M University -- Department of Computer Science
 301, Bright Building -- College Station, TX 77843-3112

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





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Mon, 12 Nov 2007 00:59:38 GMT
Raw View
Gabriel Dos Reis ha scritto:
> On Sun, 4 Nov 2007, Alberto Ganesh Barbati wrote:
>
> | Hi,
> |
> | wouldn't it make sense to declare all constructors of pair and tuple as
> | constexpr?
>
> As far as I know, std::pair contructor takes its arguments by references.
> Therfore, I don't see how the constructor could be constexpr.
>

Let's rephrase my question, then: would it make sense to modify the
current definition of pair and/or tuple so that they could be literal
types whenever all the template arguments are of literal type? For
example, the current std::pair constructor could be defined as

constexpr pair(/implementation defined/ x, /implementation defined/ y);

where the type of x is T1 if T1 is a literal type or const T1&
otherwise, and similarly for T2. (Notice that this kind of
"implementation defined" signature is already being used in the
standard, see for example the constructor of unique_ptr).

Ganesh

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





Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Mon, 12 Nov 2007 11:14:52 CST
Raw View
On Nov 12, 1:59 am, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
wrote:
> Let's rephrase my question, then: would it make sense to modify the
> current definition of pair and/or tuple so that they could be literal
> types whenever all the template arguments are of literal type? For
> example, the current std::pair constructor could be defined as
>
> constexpr pair(/implementation defined/ x, /implementation defined/ y);
>
> where the type of x is T1 if T1 is a literal type or const T1&
> otherwise, and similarly for T2. (Notice that this kind of
> "implementation defined" signature is already being used in the
> standard, see for example the constructor of unique_ptr).

Personally I think this is a good reason, see e.g. my use-case
of a function template abs both useful in constant expressions
and otherwise, the branch based on an hypothetical std::is_literal,
see

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#719

Greetings from Bremen,

Daniel

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





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Mon, 12 Nov 2007 21:22:36 GMT
Raw View
Daniel Kr=C3=BCgler ha scritto:
> On Nov 12, 1:59 am, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
> wrote:
>> Let's rephrase my question, then: would it make sense to modify the
>> current definition of pair and/or tuple so that they could be literal
>> types whenever all the template arguments are of literal type? For
>> example, the current std::pair constructor could be defined as
>>
>> constexpr pair(/implementation defined/ x, /implementation defined/ y)=
;
>>
>> where the type of x is T1 if T1 is a literal type or const T1&
>> otherwise, and similarly for T2. (Notice that this kind of
>> "implementation defined" signature is already being used in the
>> standard, see for example the constructor of unique_ptr).
>=20
> Personally I think this is a good reason, see e.g. my use-case
> of a function template abs both useful in constant expressions
> and otherwise, the branch based on an hypothetical std::is_literal,
> see
>=20
> http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#719
>=20

:-) It definitely seems that we reached the same conclusions! std::pair
could be written with std::is_literal in this way:

template <class T>
struct call_traits
{
  typedef typename conditional<
    is_literal<T>,
    T,
    typename add_lvalue_reference<
      typename add_const<T>::type
      >::type
    >::type type;
};

template <class T1, class T2>
struct pair
{
  T1 first;
  T2 second;

  constexpr pair(
    typename call_traits<T1>::type a,
    typename call_traits<T2>::type b)
    : first(a), second(b)
  {}

  /* etc. */
};

Of course, this definition assumes that constexpr is silently ignored if
either T1 or T2 is not a literal type (see discussion in thread "Defect
report: [dcl.constexpr]/5 constexpr and templates").

Cheers,

Ganesh

PS: compare this use case with boost::call_traits

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





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Sun, 4 Nov 2007 15:31:48 GMT
Raw View
Hi,

wouldn't it make sense to declare all constructors of pair and tuple as
constexpr? If I'm not mistaken, this would be sufficient to make pair a
literal type whenever both arguments are literal type and would not be
detrimental in other cases (because of 7.1.5/5). In the case of tuple,
however, we would also need to remove the user provided copy
constructor, because 3.9/11 requires the copy constructor to be trivial.
Not a big deal, as the current specification of the tuple copy
constructor matches that of an implicitly declared one.

Just my two eurocent,

Ganesh

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





Author: gdr@cs.tamu.edu (Gabriel Dos Reis)
Date: Mon, 5 Nov 2007 17:14:43 GMT
Raw View
On Sun, 4 Nov 2007, Alberto Ganesh Barbati wrote:

| Hi,
|
| wouldn't it make sense to declare all constructors of pair and tuple as
| constexpr?

As far as I know, std::pair contructor takes its arguments by references.
Therfore, I don't see how the constructor could be constexpr.

--
Dr. Gabriel Dos Reis (gdr@cs.tamu.edu), Assistant Professor
       http://www.cs.tamu.edu/people/faculty/gdr
 Texas A&M University -- Department of Computer Science
 301, Bright Building -- College Station, TX 77843-3112

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





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Mon, 5 Nov 2007 19:04:34 GMT
Raw View
Gabriel Dos Reis ha scritto:
> On Sun, 4 Nov 2007, Alberto Ganesh Barbati wrote:
>
> | Hi,
> |
> | wouldn't it make sense to declare all constructors of pair and tuple as
> | constexpr?
>
> As far as I know, std::pair contructor takes its arguments by references.
> Therfore, I don't see how the constructor could be constexpr.
>

It's true that the parameters of a constexpr *function* must be of
literal type, but I don't see in [dcl.constexpr] such a requirement
about the parameters of a constexpr *constructor*. I don't think the
requirements set in paragraph 3 (about constexpr functions) are
implicitly applied also to constructors, at least for the simple reason
that two out of four of them do not make any sense for constructors (I
am referring to those about the return value).

If the intent is that also the parameters of constexpr constructors
shall have literal type, I believe the standard should say so explicitly.

Ganesh

PS: Frankly, I do not understand why references of literal type could
not be allowed...

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





Author: gdr@cs.tamu.edu (Gabriel Dos Reis)
Date: Tue, 6 Nov 2007 00:33:34 GMT
Raw View
On Mon, 5 Nov 2007, Alberto Ganesh Barbati wrote:

| Gabriel Dos Reis ha scritto:
| > On Sun, 4 Nov 2007, Alberto Ganesh Barbati wrote:
| >
| > | Hi,
| > |
| > | wouldn't it make sense to declare all constructors of pair and tuple as
| > | constexpr?
| >
| > As far as I know, std::pair contructor takes its arguments by references.
| > Therfore, I don't see how the constructor could be constexpr.
| >
|
| It's true that the parameters of a constexpr *function* must be of
| literal type, but I don't see in [dcl.constexpr] such a requirement
| about the parameters of a constexpr *constructor*.

The constraints for the parameters apply uniformly -- and, in general,
there is no much distinction between `functions' and `constructors'.
The only exception for the parameter types is for trivial copy constructor.

[ And the only real distinction between a constexpr constructor and a
constexpr function, is that a function returns a value, and the
conctructor `yields' a value; none of them is allowed to do any non
trivial side effecting. ]

| I don't think the
| requirements set in paragraph 3 (about constexpr functions) are
| implicitly applied also to constructors, at least for the simple reason
| that two out of four of them do not make any sense for constructors (I
| am referring to those about the return value).

Well, since I wrote the wording you are reading, I can tell you
what it intends to convey :-)

I do not recall any objection in CWG at the time of review.
clearer that there is no distinction.  If CWG believes that the
wording does not say what it says, then you'll probably see a
clarification.

|
| If the intent is that also the parameters of constexpr constructors
| shall have literal type, I believe the standard should say so explicitly.
|
| Ganesh
|
| PS: Frankly, I do not understand why references of literal type could
| not be allowed...

How else can I help?

--
Dr. Gabriel Dos Reis (gdr@cs.tamu.edu), Assistant Professor
       http://www.cs.tamu.edu/people/faculty/gdr
 Texas A&M University -- Department of Computer Science
 301, Bright Building -- College Station, TX 77843-3112

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





Author: greghe@mac.com (Greg Herlihy)
Date: Tue, 6 Nov 2007 00:34:11 GMT
Raw View


On 11/5/07 11:04 AM, in article xJJXi.161524$%k.303483@twister2.libero.it=
,
"Alberto Ganesh Barbati" <AlbertoBarbati@libero.it> wrote:

> Gabriel Dos Reis ha scritto:
>> On Sun, 4 Nov 2007, Alberto Ganesh Barbati wrote:
>>=20
>> | wouldn't it make sense to declare all constructors of pair and tuple=
 as
>> | constexpr?
>>=20
>> As far as I know, std::pair contructor takes its arguments by referenc=
es.
>> Therfore, I don't see how the constructor could be constexpr.
>=20
> It's true that the parameters of a constexpr *function* must be of
> literal type, but I don't see in [dcl.constexpr] such a requirement
> about the parameters of a constexpr *constructor*. I don't think the
> requirements set in paragraph 3 (about constexpr functions) are
> implicitly applied also to constructors, at least for the simple reason
> that two out of four of them do not make any sense for constructors (I
> am referring to those about the return value).

=A77.1.5/4 imposes the following constraint on a constexpr constructor:

"every constructor involved in initializing non-static data members and b=
ase
class sub-objects shall be a constexpr constructor invoked with potential
constant expression arguments, if any."

=A75.19/2 defines a "potential constant expression":

"An expression is a 'potential constant expression' if it is a constant
expression when all occurrences of function parameters are replaced by
arbitrary constant expressions of the appropriate type."

So the arguments passed to a constexpr constructor must qualify as consta=
nt
expressions.  =A75.19/2 lists the types of subexpressions that may not ap=
pear
in a constant expression. This list includes:

"an id-expression that refers to a variable or data member of reference
type"

Therefore, references may not be used to initialize a constexpr object.

> If the intent is that also the parameters of constexpr constructors
> shall have literal type, I believe the standard should say so explicitl=
y.
>=20
> Ganesh
>=20
> PS: Frankly, I do not understand why references of literal type could
> not be allowed...

For one reason, there is no guarantee that the value of the reference is,=
 in
fact, immutable. For another, there is there no guarantee that the value =
of
the reference being passed to the constructor will be accessible at the
point that the constexpr object is being initialized.

Greg


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





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Tue, 6 Nov 2007 21:58:50 GMT
Raw View
Gabriel Dos Reis ha scritto:
> On Mon, 5 Nov 2007, Alberto Ganesh Barbati wrote:
>
> | I don't think the
> | requirements set in paragraph 3 (about constexpr functions) are
> | implicitly applied also to constructors, at least for the simple reason
> | that two out of four of them do not make any sense for constructors (I
> | am referring to those about the return value).
>
> Well, since I wrote the wording you are reading, I can tell you
> what it intends to convey :-)

I know that ;-) and I was pretty sure that that was the intent. I was
just acting as the Devil's advocate.

> I do not recall any objection in CWG at the time of review.
> clearer that there is no distinction.  If CWG believes that the
> wording does not say what it says, then you'll probably see a
> clarification.

Yes, I do believe that the wording could be clearer about this point and
I hope I'll see such a clarification.

Cheers,

Ganesh

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