blu*_*er2 5 c++ templates variadic variadic-templates
我得到一个"错误的模板参数数量(2,应该是1)"错误,我无法理解.
我有一个类为其他想要与之交互的类型提供一些辅助函数,设置第一个模板参数,在创建时它们必须自动相互兼容.为了以方便,通用的方式执行此操作,我决定使用可变参数模板,该模板旨在传递构造函数参数和要创建的对象类型的其他模板参数:
template<typename INTERNAL_TYPE>
class Linker
{
template< template<typename, typename ...> class INPUT_OBJ_TYPE, class ... TEMPLATE_ARGS, class ... CONSTRUCTOR_ARGS >
std::shared_ptr< INPUT_OBJ_TYPE<INTERNAL_TYPE,TEMPLATE_ARGS ...> > getLinked( CONSTRUCTOR_ARGS ... args )
{
std::shared_ptr< INPUT_OBJ_TYPE<INTERNAL_TYPE,TEMPLATE_ARGS ...> > ptr = std::make_shared< INPUT_OBJ_TYPE<INTERNAL_TYPE,TEMPLATE_ARGS ...> >( args... );
return ptr;
}
};
Run Code Online (Sandbox Code Playgroud)
这适用于以下类:
template<typename INTERNAL_TYPE, typename SECOND_TYPE>
class TEST_CLASS_1
{};
Run Code Online (Sandbox Code Playgroud)
也就是说,我可以做到以下几点:
Linker<int> container;
auto test_1 = container.getLinked<TEST_CLASS_1,double>();
Run Code Online (Sandbox Code Playgroud)
然后我尝试对另一个只在一个参数上进行模板化的类做同样的事情:
template<typename INTERNAL_TYPE>
class TEST_CLASS_2
{};
auto test_2 = container.getLinked<TEST_CLASS_2>();
Run Code Online (Sandbox Code Playgroud)
但得到上面提到的错误..为什么?如果我从函数声明/定义中删除了TEMPLATE_ARGS,那么我可以使用代码编写第二个测试(尽管第一个测试不再编译).所以我认为那时的编译器还没有意识到TEMPLATE_ARGS对于第二次测试是空的,并且因为有太多的模板参数而引发错误.所以我想我可能需要使用跟踪返回类型
template< template<typename, typename ...> class INPUT_OBJ_TYPE,
class ... TEMPLATE_ARGS, class ... CONSTRUCTOR_ARGS >
auto getLinked( CONSTRUCTOR_ARGS ... args )
-> std::shared_ptr< INPUT_OBJ_TYPE<TREE_TYPE,TEMPLATE_ARGS ...> >
Run Code Online (Sandbox Code Playgroud)
或使用decltype但不起作用:
template< template<typename, typename ...> class INPUT_OBJ_TYPE,
class ... TEMPLATE_ARGS, class ... CONSTRUCTOR_ARGS >
auto getLinked( CONSTRUCTOR_ARGS ... args )
->decltype(std::shared_ptr< INPUT_OBJ_TYPE<TREE_TYPE,TEMPLATE_ARGS ...> >())
Run Code Online (Sandbox Code Playgroud)
我对这个问题是对的吗?我该如何解决?
非常感谢!
这可能是编译器错误。
获得您想要的结果的一种方法是提供两个函数,您的原始函数和另一个没有不可推论参数包的函数:
template<typename INTERNAL_TYPE>
struct Linker
{
template<
template<typename, typename ...> class INPUT_OBJ_TYPE,
class ... TEMPLATE_ARGS,
class ... CONSTRUCTOR_ARGS
>
std::shared_ptr<
INPUT_OBJ_TYPE<INTERNAL_TYPE,TEMPLATE_ARGS...>
> getLinked( CONSTRUCTOR_ARGS ... args )
{
std::shared_ptr< INPUT_OBJ_TYPE<INTERNAL_TYPE,TEMPLATE_ARGS...> > ptr =
std::make_shared< INPUT_OBJ_TYPE<INTERNAL_TYPE,TEMPLATE_ARGS...> >( args... );
return ptr;
}
template<
template<typename, typename ...> class INPUT_OBJ_TYPE,
class ... CONSTRUCTOR_ARGS
>
std::shared_ptr<
INPUT_OBJ_TYPE<INTERNAL_TYPE>
> getLinked( CONSTRUCTOR_ARGS ... args )
{
std::shared_ptr< INPUT_OBJ_TYPE<INTERNAL_TYPE> > ptr =
std::make_shared< INPUT_OBJ_TYPE<INTERNAL_TYPE> >( args...);
return ptr;
}
};
Run Code Online (Sandbox Code Playgroud)