Topic: std::is_literal type traits should be provided
Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Sat, 25 Aug 2007 09:34:33 CST Raw View
Since the inclusion of constexpr in the standard draft N2369 we have
a new type category "literal", which is defined in [basic.types]/p.
11:
"A type is a literal type if it is:
- a scalar type; or
- a class type (clause 9) with
- a trivial copy constructor,
- a trivial destructor,
- at least one constexpr constructor other than the copy
constructor,
- no virtual base classes, and
- all non-static data members and base classes of literal types; or
- an array of literal type."
I strongly suggest that the standard provides a type traits for
literal
types in [meta.unary.prop] for several reasons:
a) To keep the traits in sync with existing types.
b) I see many reasons for programmers to use this trait in template
code to provide optimized template definitions for these types,
see below.
c) A user-provided definition of this trait is practically impossible
to
write portably.
The special problem of reason (c) is that I don't see currently a
way to portably test the condition for literal class types:
"- at least one constexpr constructor other than the copy
constructor"
Here follows a simply example to demonstrate it's usefulness:
template <typename T>
constexpr std::enable_if<std::is_literal<T>::value, T>::type
abs(T x) {
return x < T() ? -x : x;
}
template <typename T>
std::enable_if<!std::is_literal<T>::value, T>::type
abs(const T& x) {
return x < T() ? -x : x;
}
Here we have the possibility to provide a general abs function
template that can be used in ICE's if it's argument is a literal
type which's value is a constant expression, otherwise we
have an optimized version for arguments which are expensive
to copy and therefore need the usage of arguments of
reference type (instead of const T& we could decide to
use T&&, but that is another issue).
Proposed resolution:
In [meta.type.synop] in the group "[20.4.4.3] type properties",
just below the line
template <class T> struct is_pod;
add a new one:
template <class T> struct is_literal;
In [meta.unary.prop], table Type Property Predicates, just
below the line for the is_pod property add a new line:
column "Template":
template <class T>
struct is_literal;
column "Condition":
T is a literal type (3.9)
column "Preconditions":
T shall be a complete type, an
array of unknown bound, or
(possibly cv-qualified) void.
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: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Sat, 25 Aug 2007 20:12:27 CST Raw View
On 25 Aug., 17:34, Daniel Kr gler <daniel.krueg...@googlemail.com>
wrote:
> template <typename T>
> constexpr std::enable_if<std::is_literal<T>::value, T>::type
> abs(T x) {
> return x < T() ? -x : x;
>
> }
>
> template <typename T>
> std::enable_if<!std::is_literal<T>::value, T>::type
> abs(const T& x) {
> return x < T() ? -x : x;
>
> }
I shamelessly omitted the required typenames (I wrote too much
concepts code ;-)), so please read them as:
emplate <typename T>
constexpr typename std::enable_if<std::is_literal<T>::value, T>::type
abs(T x) {
return x < T() ? -x : x;
}
template <typename T>
typename std::enable_if<!std::is_literal<T>::value, T>::type
abs(const T& x) {
return x < T() ? -x : x;
}
With apologies,
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 ]