1 | <?xml version="1.0" encoding="utf-8" ?> |
---|
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
---|
3 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
---|
4 | <head> |
---|
5 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
---|
6 | <meta name="generator" content="Docutils 0.3.6: http://docutils.sourceforge.net/" /> |
---|
7 | <title>THE BOOST MPL LIBRARY: ETI</title> |
---|
8 | <link rel="stylesheet" href="../style.css" type="text/css" /> |
---|
9 | </head> |
---|
10 | <body class="docframe"> |
---|
11 | <table class="header"><tr class="header"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./incomplete-support-for.html" class="navigation-link">Prev</a> <a href="./resources.html" class="navigation-link">Next</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./incomplete-support-for.html" class="navigation-link">Back</a> Along</span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./portability.html" class="navigation-link">Up</a> <a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td> |
---|
12 | <td class="header-group page-location"><a href="../index.html" class="navigation-link">Front Page</a> / <a href="./technical-details.html" class="navigation-link">Technical Details</a> / <a href="./portability.html" class="navigation-link">Portability</a> / <a href="./eti.html" class="navigation-link">ETI</a></td> |
---|
13 | </tr></table><div class="header-separator"></div> |
---|
14 | <div class="section" id="eti"> |
---|
15 | <h1><a class="toc-backref" href="./portability.html#id76" name="eti">ETI</a></h1> |
---|
16 | <p>In context of C++ template problems, ETI is an abbreviation for "Early |
---|
17 | Template Instantiation" — a Microsoft Visual C++ - specific issue that |
---|
18 | has been a barrier to any serious work with templates on this platform until |
---|
19 | Microsoft developers fixed it in Visual C++ 7.1 (2003 .NET). Although the |
---|
20 | problem is relatively easy to work around if the right techniques |
---|
21 | are applied systematically through the codebase, the approach is definitely |
---|
22 | tedious and time-consuming. So, if one day you discover that you are spending |
---|
23 | too much time dealing with the issue, consider upgrading to the |
---|
24 | newer version of the compiler. In fact, seriously consider it regardless. |
---|
25 | The benefits of saved time, money and frustration are well worth the price.</p> |
---|
26 | <div class="section" id="eti-the-problem"> |
---|
27 | <h2><a name="eti-the-problem">The Problem</a></h2> |
---|
28 | <p>Here is a short demonstration of the issue with MSVC 6.x:</p> |
---|
29 | <pre class="literal-block"> |
---|
30 | template< typename F, typename T > struct apply1 |
---|
31 | { |
---|
32 | typedef typename F::template apply<T>::type type; |
---|
33 | }; |
---|
34 | </pre> |
---|
35 | <p>Trying to compiling this innocent-looking code, we get:</p> |
---|
36 | <pre class="literal-block"> |
---|
37 | portability.cpp(4) : error C2903: 'apply' : symbol is neither a class template |
---|
38 | nor a function template |
---|
39 | portability.cpp(5) : see reference to class template instantiation |
---|
40 | 'apply1<F,T>' being compiled |
---|
41 | portability.cpp(4) : error C2143: syntax error : missing ',' before '<' |
---|
42 | portability.cpp(5) : see reference to class template instantiation |
---|
43 | 'apply1<F,T>' being compiled |
---|
44 | portability.cpp(4) : error C2059: syntax error : '<' |
---|
45 | portability.cpp(5) : see reference to class template instantiation |
---|
46 | 'apply1<F,T>' being compiled |
---|
47 | </pre> |
---|
48 | <p>The "symbol is neither a class template nor a function template" part of the |
---|
49 | diagnostics is actually often an indication of ETI-related problems. Another |
---|
50 | typical error message usually says something about nested type such-and-such |
---|
51 | not being a member of a global namespace.</p> |
---|
52 | <p>Both cases are two sides of the same compiler bug, which we call |
---|
53 | "Early template instantiation": the compiler, for internal |
---|
54 | purposes, in order to process class template definitions, |
---|
55 | instantiates class templates with dummy template parameters |
---|
56 | (<tt class="literal"><span class="pre">int</span></tt>'s). That can happen both during parsing of template |
---|
57 | definitions (and such errors are most easy to identify and fix — |
---|
58 | the template definition itself just doesn't compile; the example |
---|
59 | above falls into this category), or later during template |
---|
60 | instantiation, and these one are hard to detect — the bug will |
---|
61 | only be triggered in some particular context.</p> |
---|
62 | <!-- namespace-scope: nested templates are immune? --> |
---|
63 | <p>ETI is always performed during parsing of the namespace-scope |
---|
64 | template definition, which basically means that any template |
---|
65 | definition that is rendered invalid by substituting its template |
---|
66 | parameters by <tt class="literal"><span class="pre">int</span></tt>s might not compile, as it happened with our |
---|
67 | example:</p> |
---|
68 | <pre class="literal-block"> |
---|
69 | template< typename F, typename T > struct apply1 |
---|
70 | { |
---|
71 | // typedef typename F::template apply<T>::type type; |
---|
72 | // ETI generates this: |
---|
73 | typedef typename int::template apply<int>::type type; |
---|
74 | }; |
---|
75 | </pre> |
---|
76 | <p>If you compile this, you'll get <em>exactly</em> the same diagnostics as we've just seen.</p> |
---|
77 | <p>Note that we've said "might not compile", because... well, the short answer is, |
---|
78 | "it depends". We haven't analyzed things to the point that we could tell you the |
---|
79 | exact condition when ETI leads to an error and when it doesn't, but |
---|
80 | that's not very important anyway — if it's an error, you just fix it (we'll show you how |
---|
81 | in a second), and if it's not, then you leave things as is. If one day the |
---|
82 | potential issue turns into a real one, then you apply the workaround we are about |
---|
83 | to give you.</p> |
---|
84 | </div> |
---|
85 | <div class="section" id="eti-the-symptoms"> |
---|
86 | <h2><a name="eti-the-symptoms">The Symptoms</a></h2> |
---|
87 | <p>We've already looked at the typical diagnostics, so we won't repeat |
---|
88 | ourselves. Instead we'll |
---|
89 | just mention that many MSVC's INTERNAL COMPILER ERRORs (ICEs) are, in fact, caused |
---|
90 | by an ETI-related problem somewhere deep down the instantiation stack.</p> |
---|
91 | </div> |
---|
92 | <div class="section" id="eti-the-solution"> |
---|
93 | <h2><a name="eti-the-solution">The Solution</a></h2> |
---|
94 | <p>There is no way we can change the compiler's behavior in this case, so what we have |
---|
95 | to do is to adjust to it and still make our templates do what we want. Surprisingly, |
---|
96 | in most cases it's quite simple to achieve:</p> |
---|
97 | <pre class="literal-block"> |
---|
98 | // potentially unsafe |
---|
99 | template< typename F > struct apply0 |
---|
100 | { |
---|
101 | typedef typename F::type type; |
---|
102 | }; |
---|
103 | |
---|
104 | // now ETI-safe |
---|
105 | template<> struct apply0<int> |
---|
106 | { |
---|
107 | typedef int type; |
---|
108 | }; |
---|
109 | </pre> |
---|
110 | <p>Since the original template could have never been instantiated with <tt class="literal"><span class="pre">int</span></tt>, |
---|
111 | providing a stub <tt class="literal"><span class="pre">int</span></tt> specialization is completely innocent.</p> |
---|
112 | <!-- Looks like you're missing lots of stuff, like ETI_BASE - - no? --> |
---|
113 | </div> |
---|
114 | </div> |
---|
115 | |
---|
116 | <div class="footer-separator"></div> |
---|
117 | <table class="footer"><tr class="footer"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./incomplete-support-for.html" class="navigation-link">Prev</a> <a href="./resources.html" class="navigation-link">Next</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./incomplete-support-for.html" class="navigation-link">Back</a> Along</span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./portability.html" class="navigation-link">Up</a> <a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td> |
---|
118 | </tr></table></body> |
---|
119 | </html> |
---|