mirror of
https://github.com/boostorg/more.git
synced 2024-12-26 23:30:29 +08:00
added intgral constant expression guideleines
[SVN r9832]
This commit is contained in:
parent
6dbe857852
commit
a030116020
170
index.htm
170
index.htm
@ -1,97 +1,125 @@
|
|||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
<meta http-equiv="Content-Type"
|
||||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
content="text/html; charset=iso-8859-1">
|
||||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||||
|
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
|
||||||
<title>Boost More Information</title>
|
<title>Boost More Information</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body bgcolor="#FFFFFF" text="#000000">
|
<body bgcolor="#FFFFFF" text="#000000">
|
||||||
|
|
||||||
<table border="1" bgcolor="#007F7F" cellpadding="2">
|
<table border="1" cellpadding="2" bgcolor="#007F7F">
|
||||||
<tr>
|
<tr>
|
||||||
<td bgcolor="#FFFFFF"><img src="../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86"></td>
|
<td bgcolor="#FFFFFF"><img src="../c++boost.gif"
|
||||||
<td><a href="../index.htm"><font face="Arial" color="#FFFFFF"><big>Home</big></font></a></td>
|
alt="c++boost.gif (8819 bytes)" width="277" height="86"></td>
|
||||||
<td><a href="../libs/libraries.htm"><font face="Arial" color="#FFFFFF"><big>Libraries</big></font></a></td>
|
<td><a href="../index.htm"><font color="#FFFFFF" size="4"
|
||||||
<td><a href="../people/people.htm"><font face="Arial" color="#FFFFFF"><big>People</big></font></a></td>
|
face="Arial">Home</font></a></td>
|
||||||
<td><a href="faq.htm"><font face="Arial" color="#FFFFFF"><big>FAQ</big></font></a></td>
|
<td><a href="../libs/libraries.htm"><font color="#FFFFFF"
|
||||||
<td><a href="index.htm"><font face="Arial" color="#FFFFFF"><big>More</big></font></a></td>
|
size="4" face="Arial">Libraries</font></a></td>
|
||||||
</tr>
|
<td><a href="../people/people.htm"><font color="#FFFFFF"
|
||||||
|
size="4" face="Arial">People</font></a></td>
|
||||||
|
<td><a href="faq.htm"><font color="#FFFFFF" size="4"
|
||||||
|
face="Arial">FAQ</font></a></td>
|
||||||
|
<td><a href="index.htm"><font color="#FFFFFF" size="4"
|
||||||
|
face="Arial">More</font></a></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<h1>More Information</h1>
|
<h1>More Information</h1>
|
||||||
|
|
||||||
<h2>Boost Policies</h2>
|
<h2>Boost Policies</h2>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><b><a href="discussion_policy.htm">Mailing List Discussion Policy.</a></b>
|
<p><a href="discussion_policy.htm"><b>Mailing List Discussion
|
||||||
What's acceptable and what isn't.</p>
|
Policy.</b></a> What's acceptable and what isn't.</p>
|
||||||
<p><b><a href="lib_guide.htm">Library Requirements and Guidelines</a></b>.
|
<p><a href="lib_guide.htm"><b>Library Requirements and
|
||||||
Basic standards for those preparing a submission.</p>
|
Guidelines</b></a>. Basic standards for those preparing
|
||||||
<p><a href="test_policy.htm"><b>Test Policy and Protocols</b></a>. How
|
a submission.</p>
|
||||||
testing works at Boost.</p>
|
<p><a href="test_policy.htm"><b>Test Policy and Protocols</b></a>.
|
||||||
<p><a href="submission_process.htm"><b>Library Submission Process</b></a>.
|
How testing works at Boost.</p>
|
||||||
How to submit a library to Boost.</p>
|
<p><a href="submission_process.htm"><b>Library Submission
|
||||||
<p><b><a href="formal_review_process.htm">Library Formal Review Process</a></b>.
|
Process</b></a>. How to submit a library to Boost.</p>
|
||||||
Including how to submit a review comment.</p>
|
<p><a href="formal_review_process.htm"><b>Library Formal
|
||||||
<p><b><a href="header.htm">Header Policy</a></b>. Headers are where a
|
Review Process</b></a>. Including how to submit a review
|
||||||
library contacts its users, so programming practices are particularly
|
comment.</p>
|
||||||
important.</p>
|
<p><a href="header.htm"><b>Header Policy</b></a>.
|
||||||
<p><b><a href="imp_vars.htm">Implementation Variations</a></b>.
|
Headers are where a library contacts its users, so
|
||||||
Sometimes one size fits all, sometimes it doesn't. This page deals with
|
programming practices are particularly important.</p>
|
||||||
the trade-offs.</p>
|
<p><a href="imp_vars.htm"><b>Implementation Variations</b></a>.
|
||||||
<p><b><a href="library_reuse.htm">Library Reuse</a></b>. Should Boost
|
Sometimes one size fits all, sometimes it doesn't. This
|
||||||
libraries use other boost libraries? What about the C++ Standard
|
page deals with the trade-offs.</p>
|
||||||
Library? It's another trade-off.</p>
|
<p><a href="library_reuse.htm"><b>Library Reuse</b></a>.
|
||||||
|
Should Boost libraries use other boost libraries? What
|
||||||
|
about the C++ Standard Library? It's another trade-off.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<h2>Boost Whatever</h2>
|
|
||||||
|
<h2>Boost Whatever</h2>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p> <a href="../status/compiler_status.html"><b>Compiler Status</b></a>
|
<p><a href="../status/compiler_status.html"><b>Compiler
|
||||||
Describes what
|
Status</b></a> Describes what library works with
|
||||||
library works with which compiler.</p>
|
which compiler.</p>
|
||||||
<p> <a href="regression.html"><b>Internal Regression Test Suite</b></a>
|
<p><a href="regression.html"><b>Internal Regression Test
|
||||||
Describes the tool for generating the compiler status tables
|
Suite</b></a> Describes the tool for generating
|
||||||
<p> <a href="../libs/hdr_depend.html"><b>Header Dependencies</b></a>
|
the compiler status tables </p>
|
||||||
Describes what
|
<p><a href="../libs/hdr_depend.html"><b>Header Dependencies</b></a>
|
||||||
other headers each boost header includes.</p>
|
Describes what other headers each boost header includes.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<h2>Articles and Papers</h2>
|
<h2>Articles and Papers</h2>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
<p><a href="error_handling.html"><b>Error and Exception
|
||||||
<p><a href="error_handling.html"><b>Error and Exception Handling</b></a>
|
Handling</b></a> describes approaches to errors and
|
||||||
describes approaches to errors and exceptions by <a
|
exceptions by <a href="../people/dave_abrahams.htm">David
|
||||||
href="../people/dave_abrahams.htm">David Abrahams</a>.
|
Abrahams</a>. </p>
|
||||||
|
<p><a href="count_bdy.htm"><b>Counted Body Techniques</b></a>
|
||||||
<p><b><a href="count_bdy.htm">Counted Body Techniques</a></b> by <a href="../people/kevlin_henney.htm">Kevlin
|
by <a href="../people/kevlin_henney.htm">Kevlin Henney</a> is
|
||||||
Henney</a> is must reading for those interested in reference counting, a
|
must reading for those interested in reference counting, a
|
||||||
widely used object management idiom. Originally published in <a href="http://www.accu.org/c++sig/public/Overload.html">Overload</a>
|
widely used object management idiom. Originally
|
||||||
magazine.</p>
|
published in <a
|
||||||
|
href="http://www.accu.org/c++sig/public/Overload.html">Overload</a>
|
||||||
<p><b><a href="generic_programming.html">Generic Programming
|
magazine.</p>
|
||||||
Techniques</a></b> by <a href="../people/dave_abrahams.htm">David Abrahams</a>
|
<p><a href="generic_programming.html"><b>Generic Programming
|
||||||
and <a href="../people/jeremy_siek.htm">Jeremy Siek</a>describe some of the
|
Techniques</b></a> by <a href="../people/dave_abrahams.htm">David
|
||||||
techniques used in Boost libraries.</p>
|
Abrahams</a> and <a href="../people/jeremy_siek.htm">Jeremy
|
||||||
|
Siek</a>describe some of the techniques used in Boost
|
||||||
<p><b><a href="feature_model_diagrams.htm">Feature Model Diagrams in text and
|
libraries.</p>
|
||||||
HTML</a></b> describes how to represent feature model diagrams in text form.</p>
|
<p><a href="feature_model_diagrams.htm"><b>Feature Model
|
||||||
|
Diagrams in text and HTML</b></a> describes how to represent
|
||||||
<p><b><a href="borland_cpp.html">Portability Hints: Borland C++ 5.5.1</a></b>
|
feature model diagrams in text form.</p>
|
||||||
describes Borland C++ portability issues, with suggested workarounds.</p>
|
<p><a href="borland_cpp.html"><b>Portability Hints: Borland C++
|
||||||
|
5.5.1</b></a> describes Borland C++ portability issues, with
|
||||||
<p><a href="microsoft_vcpp.html"><b>Portability Hints: Microsoft VC++ 6.0 SP4</b></a>
|
suggested workarounds.</p>
|
||||||
describes Microsoft C++ portability issues, with suggested workarounds.</p>
|
<p><a href="microsoft_vcpp.html"><b>Portability Hints:
|
||||||
|
Microsoft VC++ 6.0 SP4</b></a> describes Microsoft C++
|
||||||
|
portability issues, with suggested workarounds.</p>
|
||||||
|
<p><a href="integral_constant_guidelines.htm"><strong>Coding
|
||||||
|
Guidelines for Integral Constant Expressions</strong></a>
|
||||||
|
describes how to work through the maze of compiler related
|
||||||
|
bugs surrounding this tricky topic.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<h2>Links</h2>
|
<h2>Links</h2>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>The C++ Standard (ISO/IEC 14882) is available online as a PDF file from the
|
<p>The C++ Standard (ISO/IEC 14882) is available online as a
|
||||||
<a href="http://www.ansi.org">ANSI</a> (American National Standards Institute)
|
PDF file from the <a href="http://www.ansi.org">ANSI</a> (American
|
||||||
Electronic Standards Store. The price is $US 18.00. The document is
|
National Standards Institute) Electronic Standards Store.
|
||||||
certainly not a tutorial, but is interesting to those who care about the
|
The price is $US 18.00. The document is certainly not a
|
||||||
precise specification of the language and the standard library.</p>
|
tutorial, but is interesting to those who care about the
|
||||||
|
precise specification of the language and the standard
|
||||||
|
library.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<p> </p>
|
|
||||||
|
<p> </p>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->12 February, 2001<!--webbot bot="Timestamp" endspan i-checksum="40399" --></p>
|
|
||||||
|
|
||||||
|
<p>Revised <!--webbot bot="Timestamp" startspan s-type="EDITED"
|
||||||
|
s-format="%d %B, %Y" -->17 April, 2001<!--webbot bot="Timestamp"
|
||||||
|
i-checksum="29819" endspan --></p>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
323
integral_constant_guidelines.htm
Normal file
323
integral_constant_guidelines.htm
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type"
|
||||||
|
content="text/html; charset=iso-8859-1">
|
||||||
|
<meta name="Template"
|
||||||
|
content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
|
||||||
|
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body bgcolor="#FFFFFF" link="#0000FF" vlink="#800080">
|
||||||
|
|
||||||
|
<h2 align="center">Coding Guidelines for Integral Constant
|
||||||
|
Expressions</h2>
|
||||||
|
|
||||||
|
<p>Integral Constant Expressions are used in many places in C++;
|
||||||
|
as array bounds, as bit-field lengths, as enumerator
|
||||||
|
initialisers, and as arguments to non-type template parameters.
|
||||||
|
However many compilers have problems handling integral constant
|
||||||
|
expressions; as a result of this, programming using non-type
|
||||||
|
template parameters in particular can be fraught with difficulty,
|
||||||
|
often leading to the incorrect assumption that non-type template
|
||||||
|
parameters are unsupported by a particular compiler. This short
|
||||||
|
article is designed to provide a set of guidelines and
|
||||||
|
workarounds that, if followed, will allow integral constant
|
||||||
|
expressions to be used in a manner portable to all the compilers
|
||||||
|
currently supported by boost. Although this article is mainly
|
||||||
|
targeted at boost library authors, it may also be useful for
|
||||||
|
users who want to understand why boost code is written in a
|
||||||
|
particular way, or who want to write portable code themselves.</p>
|
||||||
|
|
||||||
|
<h3>What is an Integral Constant Expression?</h3>
|
||||||
|
|
||||||
|
<p>Integral constant expressions are described in section 5.19 of
|
||||||
|
the standard, and are sometimes referred to as "compile time
|
||||||
|
constants". An integral constant expression can be one of
|
||||||
|
the following:</p>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>A literal integral value, for example 0u or 3L.</li>
|
||||||
|
<li>An enumerator value.</li>
|
||||||
|
<li>Global integral constants, for example: <font
|
||||||
|
face="Courier New"><code><br>
|
||||||
|
</code></font><code>const int my_INTEGRAL_CONSTANT = 3;</code></li>
|
||||||
|
<li>Static member constants, for example: <br>
|
||||||
|
<code>struct myclass<br>
|
||||||
|
{ static const int value = 0; };</code></li>
|
||||||
|
<li>Member enumerator values, for example:<br>
|
||||||
|
<code>struct myclass<br>
|
||||||
|
{ enum{ value = 0 }; };</code></li>
|
||||||
|
<li>Non-type template parameters of integral or enumerator
|
||||||
|
type.</li>
|
||||||
|
<li>The result of a <code>sizeof</code> expression, for
|
||||||
|
example:<br>
|
||||||
|
<code>sizeof(foo(a, b, c))</code></li>
|
||||||
|
<li>The result of a <code>static_cast</code>, where the
|
||||||
|
target type is an integral or enumerator type, and the
|
||||||
|
argument is either another integral constant expression,
|
||||||
|
or a floating-point literal.</li>
|
||||||
|
<li>The result of applying a binary operator to two integral
|
||||||
|
constant expressions: <br>
|
||||||
|
<code>INTEGRAL_CONSTANT1 op INTEGRAL_CONSTANT2 <br>
|
||||||
|
p</code>rovided that the operator is not an assignment
|
||||||
|
operator, or comma operator.</li>
|
||||||
|
<li>The result of applying a unary operator to an integral
|
||||||
|
constant expression: <br>
|
||||||
|
<code>op INTEGRAL_CONSTANT1<br>
|
||||||
|
</code>provided that the operator is not the increment or
|
||||||
|
decrement operator.</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
|
||||||
|
<h3>Coding Guidelines</h3>
|
||||||
|
|
||||||
|
<p>The following guidelines are declared in no particular order (in
|
||||||
|
other words you need to obey all of them - sorry!), and may also
|
||||||
|
be incomplete, more guidelines may be added as compilers change
|
||||||
|
and/or more problems are encountered.</p>
|
||||||
|
|
||||||
|
<p><b><i>When declaring constants that are class members always
|
||||||
|
use the macro BOOST_STATIC_CONSTANT.</i></b></p>
|
||||||
|
|
||||||
|
<pre>template <class T>
|
||||||
|
struct myclass
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(int, value = sizeof(T));
|
||||||
|
};</pre>
|
||||||
|
|
||||||
|
<p>Rationale: not all compilers support inline initialisation of
|
||||||
|
member constants, others treat member enumerators in strange ways
|
||||||
|
(they're not always treated as integral constant expressions).
|
||||||
|
The BOOST_STATIC_CONSTANT macro uses the most appropriate method
|
||||||
|
for the compiler in question.</p>
|
||||||
|
|
||||||
|
<p><b><i>Don't declare integral constant expressions whose type
|
||||||
|
is wider than int.</i></b></p>
|
||||||
|
|
||||||
|
<p>Rationale: while in theory all integral types are usable in
|
||||||
|
integral constant expressions, in practice many compilers limit
|
||||||
|
integral constant expressions to types no wider than <b>int</b>.</p>
|
||||||
|
|
||||||
|
<p><b><i>Don't use logical operators in integral constant
|
||||||
|
expressions; use template meta-programming instead.</i></b></p>
|
||||||
|
|
||||||
|
<p>The header <boost/type_traits/ice.hpp> contains a number
|
||||||
|
of workaround templates, that fulfil the role of logical
|
||||||
|
operators, for example instead of:</p>
|
||||||
|
|
||||||
|
<p><code>INTEGRAL_CONSTANT1 | INTEGRAL_CONSTANT2</code></p>
|
||||||
|
|
||||||
|
<p>Use:</p>
|
||||||
|
|
||||||
|
<p><code>::boost::type_traits::ice_or<INTEGRAL_CONSTANT1,INTEGRAL_CONSTANT2>::value</code></p>
|
||||||
|
|
||||||
|
<p>Rationale: A number of compilers (particularly the Borland and
|
||||||
|
Microsoft compilers), tend to not to recognise integral constant
|
||||||
|
expressions involving logical operators as genuine integral
|
||||||
|
constant expressions. The problem generally only shows up when
|
||||||
|
the integral constant expression is nested deep inside template
|
||||||
|
code, and is hard to reproduce and diagnose.</p>
|
||||||
|
|
||||||
|
<p><b><i>Don't use any operators in an integral constant
|
||||||
|
expression used as a non-type template parameter</i></b></p>
|
||||||
|
|
||||||
|
<p>Rather than:</p>
|
||||||
|
|
||||||
|
<p><code>typedef myclass<INTEGRAL_CONSTANT1 ==
|
||||||
|
INTEGRAL_CONSTANT2> mytypedef;</code></p>
|
||||||
|
|
||||||
|
<p>Use:</p>
|
||||||
|
|
||||||
|
<p><code>typedef myclass< some_symbol> mytypedef;</code></p>
|
||||||
|
|
||||||
|
<p>Where <code>some_symbol</code> is the symbolic name of a an
|
||||||
|
integral constant expression whose value is <code>(INTEGRAL_CONSTANT1
|
||||||
|
== INTEGRAL_CONSTANT2).</code></p>
|
||||||
|
|
||||||
|
<p>Rationale: the older EDG based compilers (some of which are
|
||||||
|
used in the most recent version of that platform's compiler),
|
||||||
|
don't recognise expressions containing operators as non-type
|
||||||
|
template parameters, even though such expressions can be used as
|
||||||
|
integral constant expressions elsewhere.</p>
|
||||||
|
|
||||||
|
<p><b><i>Always use a fully qualified name to refer to an
|
||||||
|
integral constant expression.</i></b></p>
|
||||||
|
|
||||||
|
<p>For example:</p>
|
||||||
|
|
||||||
|
<pre><code>typedef</code> myclass< ::boost::is_integral<some_type>::value> mytypedef;</pre>
|
||||||
|
|
||||||
|
<p>Rationale: at least one compiler (Borland's), doesn't
|
||||||
|
recognise the name of a constant as an integral constant
|
||||||
|
expression unless the name is fully qualified (which is to say it
|
||||||
|
starts with ::).</p>
|
||||||
|
|
||||||
|
<p><b><i>Always leave a space after a '<' and before '::'</i></b></p>
|
||||||
|
|
||||||
|
<p>For example:</p>
|
||||||
|
|
||||||
|
<pre><code>typedef</code> myclass< ::boost::is_integral<some_type>::value> mytypedef;
|
||||||
|
^
|
||||||
|
ensure there is space here!</pre>
|
||||||
|
|
||||||
|
<p>Rationale: <: is a legal digraph in it's own right, so <::
|
||||||
|
is interpreted as the same as [:.</p>
|
||||||
|
|
||||||
|
<p><b><i>Don't use local names as integral constant expressions</i></b></p>
|
||||||
|
|
||||||
|
<p>Example:</p>
|
||||||
|
|
||||||
|
<pre>template <class T>
|
||||||
|
struct foobar
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(int, temp = computed_value);
|
||||||
|
typedef myclass<temp> mytypedef; // error
|
||||||
|
};</pre>
|
||||||
|
|
||||||
|
<p>Rationale: At least one compiler (Borland's) doesn't accept
|
||||||
|
this.</p>
|
||||||
|
|
||||||
|
<p>Although it is possible to fix this by using:</p>
|
||||||
|
|
||||||
|
<pre>template <class T>
|
||||||
|
struct foobar
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(int, temp = computed_value);
|
||||||
|
typedef foobar self_type;
|
||||||
|
typedef myclass<(self_type::temp)> mytypedef; // OK
|
||||||
|
};</pre>
|
||||||
|
|
||||||
|
<p>This breaks at least one other compiler (VC6), it is better to
|
||||||
|
move the integral constant expression computation out into a
|
||||||
|
separate traits class:</p>
|
||||||
|
|
||||||
|
<pre>template <class T>
|
||||||
|
struct foobar_helper
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(int, temp = computed_value);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct foobar
|
||||||
|
{
|
||||||
|
typedef myclass< ::foobar_helper<T>::value> mytypedef; // OK
|
||||||
|
};</pre>
|
||||||
|
|
||||||
|
<p><b><i>Don't use dependent default parameters for non-type
|
||||||
|
template parameters.</i></b></p>
|
||||||
|
|
||||||
|
<p>For example:</p>
|
||||||
|
|
||||||
|
<pre>template <class T, int I = ::boost::is_integral<T>::value> // Error can't deduce value of I in some cases.
|
||||||
|
struct foobar;</pre>
|
||||||
|
|
||||||
|
<p>Rationale: this kind of usage fails for Borland C++. Note that
|
||||||
|
this is only an issue where the default value is dependent upon a
|
||||||
|
previous template parameter, for example the following is fine:</p>
|
||||||
|
|
||||||
|
<pre>template <class T, int I = 3> // OK, default value is not dependent
|
||||||
|
struct foobar;</pre>
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
|
||||||
|
<h3>Unresolved Issues</h3>
|
||||||
|
|
||||||
|
<p>The following issues are either unresolved or have fixes that
|
||||||
|
are compiler specific, and/or break one or more of the coding
|
||||||
|
guidelines.</p>
|
||||||
|
|
||||||
|
<p><b><i>Be careful of numeric_limits</i></b></p>
|
||||||
|
|
||||||
|
<p>There are three issues here:</p>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>The header <limits> may be absent - it is
|
||||||
|
recommended that you never include <limits>
|
||||||
|
directly but use <boost/pending/limits.hpp> instead.
|
||||||
|
This header includes the "real" <limits>
|
||||||
|
header if it is available, otherwise it supplies it's own
|
||||||
|
std::numeric_limits definition. Boost also defines the
|
||||||
|
macro BOOST_NO_LIMITS if <limits> is absent.</li>
|
||||||
|
<li>The implementation of std::numeric_limits may be defined
|
||||||
|
in such a way that its static-const members may not be
|
||||||
|
usable as integral constant expressions. This contradicts
|
||||||
|
the standard but seems to be a bug that affects at least
|
||||||
|
two standard library vendors; boost defines
|
||||||
|
BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS in <boost/config.hpp>
|
||||||
|
when this is the case.</li>
|
||||||
|
<li>There is a strange bug in VC6, where the members of std::numeric_limits
|
||||||
|
can be "prematurely evaluated" in template
|
||||||
|
code, for example:</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<pre>template <class T>
|
||||||
|
struct limits_test
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT(::std::numeric_limits<T>::is_specialized);
|
||||||
|
};</pre>
|
||||||
|
|
||||||
|
<p>This code fails to compile with VC6 even though no instances
|
||||||
|
of the template are ever created; for some bizarre reason <code>::std::numeric_limits<T>::is_specialized
|
||||||
|
</code>always evaluates to false, irrespective of what the
|
||||||
|
template parameter T is. The problem seems to be confined to
|
||||||
|
expressions which depend on std::numeric_limts: for example if
|
||||||
|
you replace <code>::std::numeric_limits<T>::is_specialized</code>
|
||||||
|
with <code>::boost::is_arithmetic<T>::value</code>, then
|
||||||
|
everything is fine. The following workaround also works but
|
||||||
|
conflicts with the coding guidelines:</p>
|
||||||
|
|
||||||
|
<pre>template <class T>
|
||||||
|
struct limits_test
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(bool, check = ::std::numeric_limits<T>::is_specialized);
|
||||||
|
BOOST_STATIC_ASSERT(check);
|
||||||
|
};</pre>
|
||||||
|
|
||||||
|
<p>So it is probably best to resort to something like this:</p>
|
||||||
|
|
||||||
|
<pre>template <class T>
|
||||||
|
struct limits_test
|
||||||
|
{
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
BOOST_STATIC_CONSTANT(bool, check = ::std::numeric_limits<T>::is_specialized);
|
||||||
|
BOOST_STATIC_ASSERT(check);
|
||||||
|
#else
|
||||||
|
BOOST_STATIC_ASSERT(::std::numeric_limits<T>::is_specialized);
|
||||||
|
#endif
|
||||||
|
};</pre>
|
||||||
|
|
||||||
|
<p><b><i>Be careful how you use the sizeof operator</i></b></p>
|
||||||
|
|
||||||
|
<p>As far as I can tell, all compilers treat sizeof expressions
|
||||||
|
correctly when the argument is the name of a type (or a template-id),
|
||||||
|
however problems can occur if:</p>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>The argument is the name of a member-variable, or a local
|
||||||
|
variable (code may not compile with VC6).</li>
|
||||||
|
<li>The argument is an expression which involves the creation
|
||||||
|
of a temporary (code will not compile with Borland C++).</li>
|
||||||
|
<li>The argument is an expression involving an overloaded
|
||||||
|
function call (code compiles but the result is a garbage
|
||||||
|
value with Metroworks C++).</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p><b><i>Don't use boost::is_convertible unless you have to</i></b></p>
|
||||||
|
|
||||||
|
<p>Since is_convertible is implemented in terms of the sizeof
|
||||||
|
operator, it consistently gives the wrong value when used with
|
||||||
|
the Metroworks compiler, and may not compile with the Borland's
|
||||||
|
compiler (depending upon the template arguments used).</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p>Copyright Dr John Maddock 2001, all rights reserved.</p>
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user