【发布时间】:2020-07-30 19:15:02
【问题描述】:
我对 c++ 很陌生,对于我的第一个项目,我正在尝试编写一个 ioc 容器,通过向注册函数添加可变参数来扩展 this blog post 中描述的概念。因此,一个参数包将用于可变参数,另一个用于声明要注册的类型的依赖关系。
读了一点之后,我发现了一些类似于我最终尝试做的事情。函数如下所示:
template <class T,
template<typename ...TDependencies> typename TUnused, typename... TDependencies,
typename ...TArgs>
void RegisterSingletonClassFactory(TArgs...args)
{
std::string typeKey = typeid(T).name();
creatorMap_[typeKey] = [this, args...](){
return new T(GetInstance<TDependencies>()..., args...);
};
std::shared_ptr<IHolder> iHolder = instanceMap_[typeKey];
auto * holder = dynamic_cast<Holder<T>*>(iHolder.get());
if(holder != nullptr)
holder->instance_ = nullptr;
}
我用iocContainer_.RegisterSingletonClassFactory<boost::asio::io_context, std::tuple<>>(30); 调用它。
然而,这给了我错误“错误:没有用于调用的匹配函数”...当 clang 告诉我“候选模板被忽略:模板参数的显式指定参数无效”未使用'"。
有没有办法做到这一点?错误究竟是什么意思?
谢谢
【问题讨论】:
-
您的意思是
std::tuple而不是std::tuple<>?不过,我怀疑这里还有其他问题。 -
哦 std::tuple 而不是 std::tuple 似乎可以解决它,谢谢:)
-
为什么
TDependencies...重复了两次?你指的是GetInstance<TDependencies>()...中的哪个包? -
@Evg 并没有真正重复。第一个
TDependencies只是命名模板模板参数的参数。它对template<template<typename T, T> typename> void foo();之类的东西很有用,但在这种情况下它是多余的。在声明“第二个”之前,它超出了范围。整个template标头可以写成template <typename T, template<typename...> typename TUnused, typename... TDependencies, typename... TArgs>。函数体中唯一名为TDependencies的是第二个。 -
现在我在使用
iocContainer_.RegisterSingletonClassFactory<listener::ClearTextListener, std::tuple<boost::asio::io_context>>(boost::asio::ip::tcp::endpoint(address, portNr));调用该方法时遇到了同样的错误,这可能是一个类似的修复吗? (我当然希望如此)
标签: c++ c++17 variadic-templates