Note that there are some explanatory texts on larger screens.

plurals
  1. POPassing unique pointer to template function
    primarykey
    data
    text
    <p>I'm trying to figure out how exactly the <code>unique_ptr</code> type plays with templates in C++11, and am not having much luck: Specifically, I'm trying to make a template function which inserts a <code>unique_ptr</code> value for a given unique key in a given map if there is not already a value for the key in the map, and moves ownership of the value pointed to by the <code>unique_ptr</code> to the value in the map; If the key is already present, a runtime error is thrown.</p> <p>Now, moving the value of a <code>unique_ptr</code> is quite straightforward if you don't have to pass it to a function:</p> <pre><code>#include &lt;iostream&gt; #include &lt;memory&gt; #include &lt;unordered_map&gt; using namespace std; int main(int argc, char *argv[]) { unordered_map&lt;char, unique_ptr&lt;int&gt; &gt; testMap; char key1 = 'A'; unique_ptr&lt;int&gt; val1(new int(1)); testMap[key1] = move(val1); // Print the results cout &lt;&lt; "testMap[" &lt;&lt; key1 &lt;&lt; "] = " &lt;&lt; *testMap[key1] &lt;&lt; endl; return 0; } </code></pre> <h1>Non-template function</h1> <p>Passing the <code>unique_ptr</code> to a function is a bit more complicated:</p> <pre><code>#include &lt;iostream&gt; #include &lt;memory&gt; #include &lt;unordered_map&gt; using namespace std; void moveValueForUniqueKey(unordered_map&lt;char, unique_ptr&lt;int&gt; &gt;&amp; targetMap, char key, unique_ptr&lt;int&gt; value) throw(char) { // Check if the key is already in the map auto it = targetMap.find(key); if (it != targetMap.end()) { throw key; } else { targetMap[key] = move(value); } } int main(int argc, char *argv[]) { unordered_map&lt;char, unique_ptr&lt;int&gt; &gt; testMap; char key1 = 'A'; unique_ptr&lt;int&gt; val1(new int(1)); // Try inserting the first key-value pair try { moveValueForUniqueKey(testMap, key1, move(val1)); } catch (char&amp; duplicateKey) { cerr &lt;&lt; "Key '" &lt;&lt; duplicateKey &lt;&lt; "' already in map." &lt;&lt; endl; } // Print the key-value pairs for (pair&lt;const char, unique_ptr&lt;int&gt; &gt;&amp; entry : testMap) { cout &lt;&lt; "testMap['" &lt;&lt; entry.first &lt;&lt; "'] = " &lt;&lt; *entry.second &lt;&lt; endl; } unique_ptr&lt;int&gt; val2(new int(2)); // Try inserting the key again try { moveValueForUniqueKey(testMap, key1, move(val2)); } catch (char&amp; duplicateKey) { cerr &lt;&lt; "Key '" &lt;&lt; duplicateKey &lt;&lt; "' already in map." &lt;&lt; endl; } // Print the key-value pairs again for (pair&lt;const char, unique_ptr&lt;int&gt; &gt;&amp; entry : testMap) { cout &lt;&lt; "testMap['" &lt;&lt; entry.first &lt;&lt; "'] = " &lt;&lt; *entry.second &lt;&lt; endl; } return 0; } </code></pre> <p>This code outputs:</p> <pre><code>testMap['A'] = 1 Key 'A' already in map. testMap['A'] = 1 </code></pre> <h1>Function template</h1> <p>Now, when I try to make a template of this function, replacing the previous declaration/implementation of <code>moveValueForUniqueKey(...)</code> with:</p> <pre><code>template&lt;typename K, typename V, typename M&gt; void moveValueForUniqueKey(M targetMap, K key, unique_ptr&lt;V&gt; value) throw(char) { // Check if the key is already in the map auto it = targetMap.find(key); if (it != targetMap.end()) { throw key; } else { targetMap[key] = move(value); } } // Instantiate template function template void moveValueForUniqueKey(unordered_map&lt;char, unique_ptr&lt;int&gt; &gt;&amp; targetMap, char key, unique_ptr&lt;int&gt; value) throw(char); </code></pre> <p>I simply get the compiler error <code>use of deleted function ‘constexpr std::pair&lt;_T1, _T2&gt;::pair(const std::pair&lt;_T1, _T2&gt;&amp;) [with _T1 = const char, _T2 = std::unique_ptr&lt;int&gt;, std::pair&lt;_T1, _T2&gt; = std::pair&lt;const char, std::unique_ptr&lt;int&gt; &gt;]’</code>.</p> <p>What exactly is going on here, and how can you accomplish what I'm trying here (pass <code>unique_ptr</code> objects into template functions using move semantics)? </p>
    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.
    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