【发布时间】:2017-08-11 06:34:50
【问题描述】:
我有一个带有模板构造函数的类,如下所示:
class Foo {
private:
std::unordered_map<std::type_index, std::vector<std::function<void(BaseT*)>>> funcs;
public:
template<class T> Foo(const std::function<void(T* arg)>& func) {
auto funcToStore = [func](BaseT* a) { func(static_cast<T*>(a)); };
this->funcs[std::type_index(typeid(T))].push_back(funcToStore);
}
}
这个类的构造函数接受一个函数参数,其参数类型为T,该参数派生自某个基本类型BaseT,并将此函数存储在使用std::type_info 或T 作为键的向量映射中。
由于这是一个模板构造函数而不是普通函数,显式指定模板参数将不起作用,因为这是不允许的语法:
Foo* foo = new Foo<MyT>([](MyT* arg) { ... });
省略显式的<MyT> 也不起作用,因为模板参数无法从 lambda 参数类型推导出来。
因此,一种解决方案是将 lambda 包装在 std::function 对象中:
Foo* foo = new Foo(std::function<void(MyT*)>([](MyT* arg) { ... }));
但这显然不是一个可读性好的语法。
到目前为止,我想到的最好的方法是为std::function 使用别名:
template<class T> using Func = std::function<void(T*)>;
Foo* foo = new Foo(Func<MyT>([](MyT* arg) { ... }));
这更短,当在 lambda 参数中使用 auto 关键字时,我只需要指定实际类型 MyT 一次,所以这最终似乎是一个不错的解决方案。
但是还有其他更短的解决方案吗?这样就没有必要包装 lambda 了吗?喜欢:
Foo* foo = new Foo([](MyT* arg) { ... });
【问题讨论】:
-
@StoryTeller:很好,我更新了问题!