0

尝试编写通用代码以将默认构造的对象放置到 std 容器中并向其返回迭代器。

插入解决方案是

template<typename C>
typename C::iterator insert(C& container)
{
    return container.insert(container.end(), typename C::value_type());
}

但是 emplace 没有这样的通用接口,所以我不得不将它专门用于 2 种容器类型。我最好的尝试(没有编译)是:

template<typename C>
auto emplace(C& container)
    -> decltype(container.emplace_back())
{
    return container.emplace_back();
}

template<typename C>
auto emplace(C& container)
    -> decltype(container.emplace().first)
{
    return container.emplace().first;
}

这导致:error: void value not ignored as it ought to be

而且我不明白为什么我的 decltype 被推断为无效。

使用 gcc 4.8.5 和 -std=c++11

编辑:

转载者

int main() { std::vector v; std::vector::iterator iv = emplace(v);

    std::set<int> s;
    std::set<int>::iterator is = emplace(s);
    return 0;

}

编辑2:

第二次尝试

template<typename C>
auto emplace(C& container)
    -> decltype(container.emplace().first)
{
    return container.emplace().first;
}

template<typename C>
auto emplace(C& container)
    -> decltype(container.emplace(container.end()))
{
    return container.emplace(container.end());
}

适用于 verctor,但 set 不明确。

4

2 回答 2

4

好吧,我花了比它应该的时间更长的时间。

emplace_back()自 C++17 起仅返回已放置的对象。在此之前,它返回void,即使在 C++17 中,返回类型也是引用,而不是迭代器。

看起来您的专业化 foremplace_back()应该被修改为 return container.back()

于 2018-04-12T12:51:47.157 回答
0

感谢@Quentin,终于解决了:

// For vector, list and anything push_backable
template<typename C>
auto emplace(C& container)
    -> decltype(container.emplace_back(),container.rbegin())
{
    container.emplace_back();
    return container.rbegin();
}

// For set,unordered_set, and anything that emplace returns a pair.
template<typename C>
auto emplace(C& container)
    -> decltype(container.emplace().first)
{
    return container.emplace().first;
}
于 2018-04-15T11:50:06.500 回答