迭代可变参数模板类型

时间:2015-07-12 14:14:11

标签: c++ templates variadic-templates initializer-list multiple-arguments

我已经被困在这一段时间了,我的想法用尽了,帮助赞赏!

以下段是示例代码,以简化。

假设如下:

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>()

我知道可以按照here描述的方式迭代变量模板,但我不断遇到编译错误......

  

错误C2440:&#39;初始化&#39;:无法转换为&#39; initializer-list&#39;到&#39; std :: initializer_list&#39;

     

错误C3535:无法推断出&#39; auto&#39;来自&#39; initializer-list&#39;

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

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

有什么想法吗? 非常感谢你。

1 个答案:

答案 0 :(得分:2)

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

  

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

无效。只要所有类型都相同,C ++ 11就允许从 braced-init-list 中扣除auto。在您的情况下,std::map::erase返回size_t,因此它应该编译。 Here基本上是您的代码示例。

要解决这个问题,您可能只能明确提供类型:

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的值为voidoperator,用于避免重载www.mysite.com/setlanguage/spanish的问题。