Note that there are some explanatory texts on larger screens.

plurals
  1. POFunction signature-like expressions as C++ template arguments
    primarykey
    data
    text
    <p>I was looking at Don Clugston's <a href="http://www.codeproject.com/KB/cpp/FastDelegate.aspx">FastDelegate</a> mini-library and noticed a weird syntactical trick with the following structure:</p> <pre><code>TemplateClass&lt; void( int, int ) &gt; Object; </code></pre> <p>It almost appears as if a function signature is being used as an argument to a template instance declaration.</p> <p>This technique (whose presence in FastDelegate is apparently due to one Jody Hagins) was used to simplify the declaration of template instances with a semi-arbitrary number of template parameters.</p> <p>To wit, it allowed this something like the following:</p> <pre><code>// A template with one parameter template&lt;typename _T1&gt; struct Object1 { _T1 m_member1; }; // A template with two parameters template&lt;typename _T1, typename _T2&gt; struct Object2 { _T1 m_member1; _T2 m_member2; }; // A forward declaration template&lt;typename _Signature&gt; struct Object; // Some derived types using "function signature"-style template parameters template&lt;typename _Dummy, typename _T1&gt; struct Object&lt;_Dummy(_T1)&gt; : public Object1&lt;_T1&gt; {}; template&lt;typename _Dummy, typename _T1, typename _T2&gt; struct Object&lt;_Dummy(_T1, _T2)&gt; : public Object2&lt;_T1, _T2&gt; {}; // A. "Vanilla" object declarations Object1&lt;int&gt; IntObjectA; Object2&lt;int, char&gt; IntCharObjectA; // B. Nifty, but equivalent, object declarations typedef void UnusedType; Object&lt; UnusedType(int) &gt; IntObjectB; Object&lt; UnusedType(int, char) &gt; IntCharObjectB; // C. Even niftier, and still equivalent, object declarations #define DeclareObject( ... ) Object&lt; UnusedType( __VA_ARGS__ ) &gt; DeclareObject( int ) IntObjectC; DeclareObject( int, char ) IntCharObjectC; </code></pre> <p>Despite the real whiff of hackiness, I find this kind of spoofy emulation of variadic template arguments to be pretty mind-blowing.</p> <p>The real meat of this trick seems to be the fact that I can pass textual constructs like "Type1(Type2, Type3)" as arguments to templates. So here are my questions: How exactly does the compiler interpret this construct? Is it a function signature? Or, is it just a text pattern with parentheses in it? If the former, then does this imply that any arbitrary function signature is a valid type as far as the template processor is concerned?</p> <p>A follow-up question would be that since the above code sample is valid code, why doesn't the C++ standard just allow you to do something like the following, which does not compile?</p> <pre><code>template&lt;typename _T1&gt; struct Object { _T1 m_member1; }; // Note the class identifier is also "Object" template&lt;typename _T1, typename _T2&gt; struct Object { _T1 m_member1; _T2 m_member2; }; Object&lt;int&gt; IntObject; Object&lt;int, char&gt; IntCharObject; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload