Note that there are some explanatory texts on larger screens.

plurals
  1. POC++: Generate a compile error if user tries to instantiate a class template wihout instantiating a corresponding function template
    primarykey
    data
    text
    <p>In a library that I'm writing I have a class:</p> <pre><code>template&lt;typename T&gt; class my_class {}; </code></pre> <p>and a function:</p> <pre><code>template&lt;typename T&gt; void my_function(...) {}; </code></pre> <p>I want to guarantee that a user of my code has called <code>my_function&lt;T&gt;</code> somewhere in their code if they try to instantiate <code>my_class&lt;T&gt;</code>. In other words, I want to generate a compile error if they try to instantiate the <code>my_class</code> template without also instantiating the corresponding <code>my_function</code> template.</p> <p>Example:</p> <pre><code>int main() { my_func&lt;int&gt;() // cause instantiation of my_func&lt;int&gt; my_class&lt;int&gt; foo; // okay, because my_func&lt;int&gt; exists my_class&lt;char&gt; bar; // compile error! my_func&lt;char&gt; does not exist } </code></pre> <p>Note that <code>my_class&lt;T&gt;</code> does not need to use <code>my_func&lt;T&gt;</code> internally so instantiating it won't automatically cause <code>my_func&lt;T&gt;</code> to become instantiated.</p> <p><strong>Edit[0]:</strong> I can't call <code>my_func&lt;T&gt;</code> myself because I need the user to call it and pass in information that tells the library how to handle <code>my_class&lt;T&gt;</code>. ie. If they want to use a <code>my_class&lt;char&gt;</code> they need to explicitly say so in a particular place in the code. I could make <code>my_class&lt;T&gt;</code> constructor test whether <code>my_func&lt;T&gt;</code> has been called generate a run-time error if it hasn't but I'd prefer to be able to generate a compile-time error since it's knowable at compile-time whether <code>my_func&lt;T&gt;</code> is ever used.</p> <p><strong>Edit[1]:</strong> One less-than-ideal way to do it would be to make a <code>MY_FUNC</code> macro that creates a template specialisation of an otherwise incomplete template class...</p> <pre><code>template&lt;typename T&gt; class incomplete; #define MY_FUNC(T) template&lt;&gt; incomplete&lt;T&gt; { static const bool x = my_func&lt;T&gt;(); }; template&lt;typename T&gt; class my_class { template&lt;size_t i&gt; class empty {}; typedef empty&lt;sizeof(incomplete&lt;T&gt;)&gt; break_everything; } </code></pre> <p>Now the user can only use a <code>my_class&lt;T&gt;</code> if <code>MY_FUNC(T)</code> is used somewhere. However I'd prefer a solution that doesn't use macros and doesn't force the user to use <code>MY_FUNC</code> at global scope rather than in a function.</p> <p><strong>Edit[2]:</strong> Thanks for the answers everyone. I realise it's impossible to guarantee at compile that the user will isn't calling <code>my_func&lt;T&gt;</code> incorrectly. But I can make it pretty unlikely and make it generate a runtime error early on if they do.</p> <p>They're supposed to define a function called, lets say, <code>initialise_library</code>. The function looks like this:</p> <pre><code>void initialise_library() { my_func&lt;int&gt;(); my_func&lt;char&gt;(); etc.. } </code></pre> <p>During the library initialisation, it checks to make sure none of the <code>my_func</code>s have been called. It then calls <code>initialise_library</code>. It then checks to make sure all of the <code>my_funcs</code> have been called. This much is doable. If the user hasn't defined <code>initialise_library</code> they get a linker error. If they haven't called <code>my_func&lt;T&gt;</code> somewhere in their program for a <code>my_class&lt;T&gt;</code> that they use then (idealy) they get a compile error. If they've defined <code>initialise_library</code> <em>and</em> they've used <code>my_func&lt;T&gt;</code> somewhere <em>but</em> they've used it in the wrong place they get a runtime error when their program starts up.</p> <p>Basically I want to stop them from adding a <code>my_class&lt;T&gt;</code> somewhere in their code and forgetting to put <code>my_func&lt;T&gt;()</code> in <code>initialise_library</code>, because that's something they're likely to do. The only way to runtime check this would be during the construction of <code>my_class&lt;T&gt;</code>. This will be an annoyingly late time to make this check if they only use <code>my_class&lt;T&gt;</code> in a deep and rarely-used chunk of code.</p>
    singulars
    1. This table or related slice is empty.
    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.
    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