迭代可变模板类型
Iterating variadic template types
我已经坚持了一段时间,但我 运行 没有想法,感谢帮助!
为了简化起见,以下部分是示例代码。
假设如下:
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 所述遍历可变参数模板,但我总是遇到编译错误...
error C2440: 'initializing': cannot convert from 'initializer-list' to 'std::initializer_list'
error C3535: cannot deduce type for 'auto' from 'initializer-list'
...当我尝试 运行 此代码时:
template<typename ...T>
void remove() {
// Iterate through templates somehow and...
auto list = {(container.erase(typeid(T)))... };
}
有什么想法吗?
非常感谢。
我猜你 运行 遇到了一个 MSVC 错误。编译错误:
error C3535: cannot deduce type for 'auto' from 'initializer-list'
无效。 C++11 确实允许从 braced-init-list 推导 auto
,只要所有类型都相同。在你的例子中,std::map::erase
returns a size_t
,所以它应该编译。 Here 基本上是您的代码示例。
要解决这个问题,您可以明确提供类型:
size_t dummy[] = {m.erase(typeid(T))...};
或者,以防万一有人传入任何类型,在前面加上一个零:
size_t dummy[] = {0u, m.erase(typeid(T))...};
这样一来,数组将始终至少有一个元素。 在他的评论中建议的更典型的用法如下:
int dummy[] = {0, (void(m.erase(typeid(T)), 0)... };
无论您将 m.erase(...)
替换为什么表达式,这都有效,因为 (..., 0)
的值是 0
。 void
用于避免重载 operator,
的问题。
我已经坚持了一段时间,但我 运行 没有想法,感谢帮助!
为了简化起见,以下部分是示例代码。
假设如下:
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 所述遍历可变参数模板,但我总是遇到编译错误...
error C2440: 'initializing': cannot convert from 'initializer-list' to 'std::initializer_list'
error C3535: cannot deduce type for 'auto' from 'initializer-list'
...当我尝试 运行 此代码时:
template<typename ...T>
void remove() {
// Iterate through templates somehow and...
auto list = {(container.erase(typeid(T)))... };
}
有什么想法吗? 非常感谢。
我猜你 运行 遇到了一个 MSVC 错误。编译错误:
error C3535: cannot deduce type for 'auto' from 'initializer-list'
无效。 C++11 确实允许从 braced-init-list 推导 auto
,只要所有类型都相同。在你的例子中,std::map::erase
returns a size_t
,所以它应该编译。 Here 基本上是您的代码示例。
要解决这个问题,您可以明确提供类型:
size_t dummy[] = {m.erase(typeid(T))...};
或者,以防万一有人传入任何类型,在前面加上一个零:
size_t dummy[] = {0u, m.erase(typeid(T))...};
这样一来,数组将始终至少有一个元素。
int dummy[] = {0, (void(m.erase(typeid(T)), 0)... };
无论您将 m.erase(...)
替换为什么表达式,这都有效,因为 (..., 0)
的值是 0
。 void
用于避免重载 operator,
的问题。