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