传递唯一的指针给模板函数
Passing unique pointer to template function
我想弄清楚unique_ptr
类型是如何在c++ 11中与模板一起发挥作用的,并且我没有太多的运气:具体来说,我试图制作一个模板函数,如果在给定的地图中还没有键的值,则在给定的地图中插入一个unique_ptr
值,并将unique_ptr
指向的值的所有权移动到地图中的值;如果键已经存在,则抛出运行时错误。
现在,移动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;
}
<标题> Non-template函数将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, "!");
并且您将看到断言没有触发(实例)。
你得到的编译错误最有可能的原因是你没有在你的函数模板中使用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中已被弃用。
首先需要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_refrence<T&>::type
。你为什么不直接用T
呢?
template<typename K, typename V, typename M>
void moveValueForUniqueKey(M targetMap, K key, unique_ptr<V> value) throw(char)
{...}
std::unique_ptr
不能被复制,所以您应该简单地将的左值移到参数中。例如,您的主程序中有一个无效行。改变这个:
moveValueForUniqueKey(testMap, key1, move(val2));
moveValueForUniqueKey(move(testMap), key1, move(val2));
// ^^^^^^^^^^^^^
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针