完美的转发与大括号附上的初始化列表



对于个人教育,我正在编写哈希表的基本实现(尽管下面的内容可能与任何包含可以列表初始化的类型的容器有关(,并希望尽我所能使用c++的现代元素,特别是在这种情况下,完美的转发。

在这样做的过程中,我发现我无法找出一个特定的情况——编写一个插入函数,在使用大括号括起来的初始化程序列表的同时实现完美的转发。当尝试模拟类似std::unordered_map的插入样式container.insert({key,value})时,如果不写这一点,就无法使用完美转发。

具体来说,我有一些哈希表类,它将键和值作为std::pair<T,U>对象存储在(例如(存储在向量中的存储桶中的列表中(对于哈希+链接方法(

template<typename T,typename U, typename func = std::hash<T> >
class HashTable{
std::vector<std::list<std::pair<T,U> > > data;
...
public: 
template<typename V>
bool insert(V &&entry)
{
//insert into the table by forwarding entry as
... = std::forward<V>(entry);
return true; //plus some logic for failed insertion if key already exists
}
};

然后,我通过调用(如(插入左值和右值来测试我的容器

std::pair<int32_t,std::string> example = {12,"bike"};
myHashTableObject.insert(example);                                  //example 1
myHashTableObject.insert(std::pair<int32_t,std::string>(15,"car")); //example 2
myHashTableObject.insert({28,"bus"});                               //example 3

示例1和2编译并运行良好,但示例3没有编译器错误(例如,使用第三个模板参数func的默认类型,但错误是用户提供的散列的分析(

error: no matching function for call to ‘HashTable<int, std::__cxx11::basic_string<char> >::insert(<brace-enclosed initializer list>)’

这似乎是合理的——它不知道如何解释初始化列表应该构造什么类型的对象。

一个简单的";解决方案";就是忘记完美转发,而只是重载insert函数以接受对std::pair<T,U>的右值引用和常量左值引用。但感觉应该有更好的方法。

有没有一种明显的方法可以通知编译器,尽管它是一个模板变量V以实现完美的转发,但它应该是对std::pair<T,U>参数的某种引用?

STL中容器的常见实现是如何实现这一点的?或者他们只是超载了?

{..}没有类型,因此无法在insert中推导。

你可以通过提供默认的模板类型来解决这个问题:

template<typename V = std::pair<T, U>> // default to handle {..}
bool insert(V&& entry)
{
... = std::forward<V>(entry);
// ..
return true;
}

演示

最新更新