变量函数的C++多参数包 我对C++是很新的,我的第一个项目是尝试写一个IOC容器,通过在注册函数中添加变量参数来扩展描述的概念。因此,一个参数包将用于可变参数,另一个用于声明要注册的类型的依赖项

变量函数的C++多参数包 我对C++是很新的,我的第一个项目是尝试写一个IOC容器,通过在注册函数中添加变量参数来扩展描述的概念。因此,一个参数包将用于可变参数,另一个用于声明要注册的类型的依赖项,c++,c++17,variadic-templates,C++,C++17,Variadic Templates,读了一点之后,我发现了一些类似于我最后尝试做的事情。函数如下所示: template <class T, template<typename ...TDependencies> typename TUnused, typename... TDependencies, typename ...TArgs> void RegisterSingletonClassFactory(TArgs...args) { std::string ty

读了一点之后,我发现了一些类似于我最后尝试做的事情。函数如下所示:

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.RegisterSingletonClassFactory30;来称呼它

然而,这给了我一个错误:没有匹配的函数来调用。。。当clang告诉我忽略候选模板时:为模板参数“TUnused”显式指定的参数无效

有办法做到这一点吗?这个错误到底意味着什么

谢谢

这个错误到底意味着什么

这个错误意味着你的电话

iocContainer_.RegisterSingletonClassFactory<boost::asio::io_context, std::tuple<>>(30);
所以你可以显式T和a,也许是空的TDependencies。。。类型列表

塔格人。。。列表是从参数推导出来的

下面是一个愚蠢但可编译的C++17示例

#include <iostream>

template <typename T, typename... TDependencies, typename ...TArgs>
void foo (TArgs...args)
 {
   std::cout << "T:" << typeid(T).name() << std::endl;

   std::cout << "TDependecies list:" << std::endl;

   ((std::cout << "- " << typeid(TDependencies).name() << std::endl), ...);

   std::cout << "TArgs list:" << std::endl;

   ((std::cout << "- " << typeid(TArgs).name() << std::endl), ...);
 }

int main()
 {
   foo<std::string, short, int, long, long long>(0, 1l, 2ll);   
 }
其中T是std::string第一个显式模板参数TDependencies。。。是short,int,long,long-long以下显式模板参数和目标。。。是从0,1l,2ll参数推导出来的int,long,long

请注意,您不需要tunussed模板参数

这个错误到底意味着什么

这个错误意味着你的电话

iocContainer_.RegisterSingletonClassFactory<boost::asio::io_context, std::tuple<>>(30);
所以你可以显式T和a,也许是空的TDependencies。。。类型列表

塔格人。。。列表是从参数推导出来的

下面是一个愚蠢但可编译的C++17示例

#include <iostream>

template <typename T, typename... TDependencies, typename ...TArgs>
void foo (TArgs...args)
 {
   std::cout << "T:" << typeid(T).name() << std::endl;

   std::cout << "TDependecies list:" << std::endl;

   ((std::cout << "- " << typeid(TDependencies).name() << std::endl), ...);

   std::cout << "TArgs list:" << std::endl;

   ((std::cout << "- " << typeid(TArgs).name() << std::endl), ...);
 }

int main()
 {
   foo<std::string, short, int, long, long long>(0, 1l, 2ll);   
 }
其中T是std::string第一个显式模板参数TDependencies。。。是short,int,long,long-long以下显式模板参数和目标。。。是从0,1l,2ll参数推导出来的int,long,long

请注意,您不需要TUnused模板参数。

现在很清楚,原始问题中并不真正需要std::tuple,但为了完整性,让我举一个示例,说明如何从std::tuple-like-types1中提取依赖项。我们所需要的只是一个额外的间接层次:

template<class T>
struct wrapper {};

template<class T, template<class...> class Unused, 
         class... Dependencies, class... Args>
void RegisterSingletonClassFactoryImpl(
    wrapper<Unused<Dependencies...>>, Args... args) {

    std::string typeKey = typeid(T).name();
    creatorMap_[typeKey] = [this, args...]() {
        return new T(GetInstance<Dependencies>()..., args...);
    }; 
    // ...
}

template<class T, class Unused, class... Args>
void RegisterSingletonClassFactory(Args... args) {
    RegisterSingletonClassFactoryImpl<T>(wrapper<Unused>{}, args...);
}
可以用来代替std::tuple。

现在很清楚,std::tuple在最初的问题中并不是真正需要的,但为了完整性,让我举一个例子,说明如何从std::tuple类型1中提取依赖项。我们所需要的只是一个额外的间接层次:

template<class T>
struct wrapper {};

template<class T, template<class...> class Unused, 
         class... Dependencies, class... Args>
void RegisterSingletonClassFactoryImpl(
    wrapper<Unused<Dependencies...>>, Args... args) {

    std::string typeKey = typeid(T).name();
    creatorMap_[typeKey] = [this, args...]() {
        return new T(GetInstance<Dependencies>()..., args...);
    }; 
    // ...
}

template<class T, class Unused, class... Args>
void RegisterSingletonClassFactory(Args... args) {
    RegisterSingletonClassFactoryImpl<T>(wrapper<Unused>{}, args...);
}

可以用来代替std::tuple。

你是说std::tuple代替std::tuple吗?不过,我怀疑这里还有其他问题。噢,std::tuple而不是std::tuple似乎可以解决它,谢谢:为什么TDependencies。。。重复两次?在GetInstance中你指的是哪一个包…?@Evg它实际上并不重复。第一个TDependencies只是命名模板参数的参数。这对于模板void foo;,但在这种情况下,这是多余的。它在声明第二个之前超出范围。整个模板头可以写入模板。函数体中唯一一个名为TDependencies的东西是第二个;这可能是类似的修复方法吗?我当然希望你指的是std::tuple而不是std::tuple?不过,我怀疑这里还有其他问题。噢,std::tuple而不是std::tuple似乎可以解决它,谢谢:为什么TDependencies。。。重复两次?在GetInstance中你指的是哪一个包…?@Evg它实际上并不重复。第一个TDependencies只是命名模板参数的参数。这对于模板void foo;,但在这种情况下,这是多余的。它在声明第二个之前超出范围。整个模板头可以写入模板。函数体中唯一一个名为TDependencies的东西是第二个;这可能是类似的修复方法吗?我当然希望如此
template<class...>
class type_list;