c++ - 将唯一指针传递给模板函数

标签 c++ templates c++11 unique-ptr

我想弄清楚 unique_ptr 到底是怎么回事type 在 C++11 中使用模板,但运气不佳:具体来说,我正在尝试制作一个插入 unique_ptr 的模板函数。如果映射中的键没有值,则给定映射中给定唯一键的值,并移动 unique_ptr 指向的值的所有权。 map 中的值;如果 key 已经存在,则会引发运行时错误。

现在,移动一个 unique_ptr 的值如果您不必将其传递给函数,则非常简单:

#include <iostream>
#include <memory>
#include <unordered_map>

using namespace std;

int main(int argc, char *argv[])
{
    unordered_map<char, unique_ptr<int> > testMap;

    char key1 = 'A';
    unique_ptr<int> val1(new int(1));
    testMap[key1] = move(val1);

    // Print the results
    cout << "testMap[" << key1 << "] = " << *testMap[key1] << endl;

    return 0;

}

非模板函数

传递 unique_ptr函数有点复杂:

#include <iostream>
#include <memory>
#include <unordered_map>

using namespace std;

void moveValueForUniqueKey(unordered_map<char, unique_ptr<int> >& targetMap, char key, unique_ptr<int> 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<char, unique_ptr<int> > testMap;
    char key1 = 'A';
    unique_ptr<int> val1(new int(1));

    // Try inserting the first key-value pair
    try
    {
        moveValueForUniqueKey(testMap, key1, move(val1));
    }
    catch (char& duplicateKey)
    {
        cerr << "Key '" << duplicateKey << "' already in map." << endl;
    }

    // Print the key-value pairs
    for (pair<const char, unique_ptr<int> >& entry : testMap)
    {
        cout << "testMap['" << entry.first << "'] = " << *entry.second << endl;
    }

    unique_ptr<int> val2(new int(2));

    // Try inserting the key again
    try
    {
        moveValueForUniqueKey(testMap, key1, move(val2));
    }
    catch (char& duplicateKey)
    {
        cerr << "Key '" << duplicateKey << "' already in map." << endl;
    }

    // Print the key-value pairs again
    for (pair<const char, unique_ptr<int> >& entry : testMap)
    {
        cout << "testMap['" << entry.first << "'] = " << *entry.second << endl;
    }

    return 0;

}

这段代码输出:

testMap['A'] = 1
Key 'A' already in map.
testMap['A'] = 1

函数模板

现在,当我尝试制作此函数的模板时,替换之前 moveValueForUniqueKey(...) 的声明/实现与:

template<typename K, typename V, typename M>
void moveValueForUniqueKey(M targetMap, K key, unique_ptr<V> 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<char, unique_ptr<int> >& targetMap, char key, unique_ptr<int> value) throw(char);

我只是得到编译器错误 use of deleted function ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const char, _T2 = std::unique_ptr<int>, std::pair<_T1, _T2> = std::pair<const char, std::unique_ptr<int> >]’ .

这里到底发生了什么,您如何完成我在这里尝试的事情(使用移动语义将 unique_ptr 对象传递到模板函数中)?

最佳答案

首先,这个:

remove_reference<unique_ptr<int>&>::type

就相当于这样:

unique_ptr<int>

我看不到那里需要 remove_reference。要说服自己,请尝试以下操作:

#include <type_traits>
#include <memory>

static_assert(std::is_same<
    remove_reference<unique_ptr<int>&>::type, 
    unique_ptr<int>>::value, "!");

您会看到断言没有触发 (live example)。

您收到编译器错误的最可能原因是您没有在函数模板中使用 typename 消歧器:

template<typename K, typename V, typename M>
void moveValueForUniqueKey(M targetMap, K key, 
    typename remove_reference<unique_ptr<V>&>::type value) throw(char)
//  ^^^^^^^^
{
    // ...
}

但同样,没有理由在那里使用 remove_reference:

template<typename K, typename V, typename M>
void moveValueForUniqueKey(M targetMap, K key, unique_ptr<V> value) throw(char)
//                                             ^^^^^^^^^^^^^
{
    // ...
}

最后,请记住动态异常规范在 C++11 中已弃用。

关于c++ - 将唯一指针传递给模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16950401/

相关文章:

c++ - IShellBrowser::QueryActiveShellView 方法的实现者是否应该为调用者调用 AddRef?

C++ 当模板参数相同时优化类模板函数

c++ - 使用 automake 和 autoconf 安装 C++ 程序

c++ - std::set 中的自定义仿函数

c++ - to_string 不是 std 的成员,g++ (mingw)

java - 如何使用objdump反汇编OpenJDK(bin/java)?

c++ - 警告 C4267 : 'initializing' : conversion from 'size_t' to 'UINT'

C++:将字符串和填充内容拆分为 std::vector 的优雅方式

c++ - 为什么 C++ 模板接受数组并不比一个接受指针 (bis) 更专业?

php - 网站多页 |模板 |搜索