参数包扩展不起作用

时间:2016-12-30 08:02:00

标签: c++ c++11 parameters

我尝试创建名为std::set的{​​{1}}的多路复用,它可以在各种比较对象的透视图中查看元素。例如,一组扑克牌可以排序第一,排名第二,或排第一,排第二; NDos::set_multiplex可以方便地执行此操作。 NDos::set_multiplex通过继承多个NDos::set_multiplex来实现这一点,一个存储元素,另一个存储元素的迭代器。 std::setNDos::IterComp类型,用于比较两个迭代器引用的元素。

以下是代码:

Callable

参数包未正确扩展。 G ++ 6.2报告每次扩展时的错误:(在函数/*...*/ namespace NDos { template <class T, class Comp0, class... Comps> class set_multiplex : private std::set<T, Comp0>, private std::set< typename std::set<T, Comp0>::iterator, IterComp<typename std::set<T, Comp0>::iterator, Comps> >... { private: typedef std::set<T, Comp0> Base0; public: /*...*/ using typename Base0::iterator; using typename Base0::const_iterator; using typename Base0::reverse_iterator; using typename Base0::const_reverse_iterator; #define Bases std::set<iterator, IterComp<iterator, Comps>> /*constructors*/ // copy constructor : default // move constructor : default // copy assignment operator : default // move assignment operator : default // destructor : default /*...*/ void clear() noexcept { Base0::clear(); Bases::clear()...; } iterator insert(const T &value) { return emplace(value); } iterator insert(T &&value) { return emplace(std::move(value)); } iterator insert(const_iterator pos, const T &value) { return emplace_hint(pos, value); } iterator insert(const_iterator pos, T &&value) { return emplace_hint(pos, std::move(value)); } template <class InputIt> void insert(InputIt first, InputIt last) { while (first != last) insert(*first++); } void insert(std::initializer_list<T> ilist) { insert(std::make_move_iterator(ilist.begin()), std::make_move_iterator(ilist.end())); } template <class... Args> iterator emplace(Args &&...args) { iterator i0 = Base0::emplace(std::forward<Args>(args)...).first; Bases::insert(i0)...; return i0; } template <class... Args> iterator emplace_hint(const_iterator pos, Args &&...args) { iterator i0 = Base0::emplace_hint(pos, std::forward<Args>(args)...).first; Bases::insert(i0)...; return i0; } iterator erase(iterator pos) { Bases::erase(pos)...; return Base0::erase(pos); } iterator erase(const_iterator first, const_iterator last) { while (first != last) erase(first++); } size_type erase(const T &key) { iterator pos = find(key); if (pos == end()) return 0; else { erase(pos); return 1; } } void swap(set_multiplex &other) noexcept { Base0::swap(other); Bases::swap(other)...; } /*...*/ #undef Bases }; } clearemplaceemplace_hinterase

swap

为什么会发生这种情况?

1 个答案:

答案 0 :(得分:2)

在C ++ 11中,你不能简单地这样做:

Bases::clear()...;

对于您以这种方式使用...的所有其他地方也会发生同样的情况:

Bases::insert(i0)...;
Bases::erase(pos)...;
Bases::swap(other)...;

尝试使用以下内容:

void clear() noexcept {
    Base0::clear();
    int _[] = { 0, (Bases::clear(), 0)... };
    (void)_; // silent warnings, nothing more
}

这是在等待C ++ 17及其折叠表达式时常用的技巧。

swap函数的特别提及:如果您将otherBase0交换,other理论上会在交换后包含Base0中的数据。再次使用它进行另一次交换似乎不是一个好主意 也许您应该检查swap函数的实现。