6

我已经坚持了一段时间,我的想法已经用完了,感谢您的帮助!

以下部分是示例代码,为简化起见。

假设如下:

class Base; 
class DerivedA : public Base; 
class DerivedB : public Base;

还有这个:

class Manager {
public:
    std::map<std::type_index, Base*> container;

    template<typename ...T>
    void remove() {
        // Iterate through templates somehow and...
        container.erase(typeid(T));
    }
}

基本上,我通过使用 std::type_index 作为键将派生类的唯一实例存储在容器中。允许我做类似的事情:

manager.remove<DerivedA>();

话虽如此,我希望能够做同样的事情,但允许多个模板直接一次删除多个实例,例如:

manager.remove<DerivedA, DerivedB>()

我知道可以按照此处所述迭代可变参数模板,但我不断收到编译错误...

错误 C2440:“正在初始化”:无法从“初始化器列表”转换为“std::initializer_list”

错误 C3535:无法从“initializer-list”中推断“auto”的类型

...当我尝试运行此代码时:

template<typename ...T>
void remove() {
    // Iterate through templates somehow and...
    auto list = {(container.erase(typeid(T)))... };
}

有任何想法吗?非常感谢你。

4

1 回答 1

2

我猜你刚刚遇到了一个 MSVC 错误。编译错误:

错误 C3535:无法从“initializer-list”中推断“auto”的类型

无效。只要所有类型都相同,C++11 确实允许auto花括号初始化列表中扣除。在您的情况下,std::map::erase返回 a size_t,因此它应该编译。是一个基本上包含您的代码的示例。

为了解决这个问题,您可能只能显式提供类型:

size_t dummy[] = {m.erase(typeid(T))...};

或者,以防万一有人没有传入任何类型,在前面加上一个零:

size_t dummy[] = {0u, m.erase(typeid(T))...};

这样,数组将始终具有至少一个元素。Kerrek在他的评论中建议的更典型的用法如下:

int dummy[] = {0, (void(m.erase(typeid(T)), 0)... };

无论您将替换为何种表达式,这都将起作用m.erase(...),因为 的(..., 0)值为0。是为了void避免重载问题operator,

于 2015-07-12T15:22:01.207 回答