通过参数推导多参数模板中的第一个模板参数

Bla*_*aws 5 c++ templates template-argument-deduction

首先是我的问题,然后解释我正在尝试做什么,因为我可能会错误地处理问题。

是否可以在指定其他参数的同时从参数中推导出多参数模板中的第一个模板参数。

例子:

 template<class A, class B>
 B function(A object)
 { 
     return B(A);
 }
Run Code Online (Sandbox Code Playgroud)

称为:

 function<BType>(AInstance);
Run Code Online (Sandbox Code Playgroud)

我找不到一种方法来完成这项工作。

编辑:另一个例子可能更适合我下面的问题,正如我收到的第一条评论所表明的那样

例子:

 template<class A, A::B foo>
 void function(A object)
 { 
     object.doSomethingWithTypeA::B(foo);
 }
Run Code Online (Sandbox Code Playgroud)

称为:

 function<A::BInstance>(AInstance);
Run Code Online (Sandbox Code Playgroud)

不同之处在于,第二个模板参数取决于第一个模板参数的具体类型,因此我无法切换模板参数。

现在描述我正在尝试做的事情:

我目前正在尝试创建一个模板通用仿函数类,它可以采用自由函数或成员函数并将其包装到仿函数中。

我成功地实现了我的目标,但现在我想让一切变得更加用户友好。目前创建函子的模板化函数如下所示:

template <class T, ReturnType (T::*Method)(FunctionArguments...)>
static constexpr UniversalFunctor Create(T* object) {
   return {object, MethodWrapper<T, Method>};
}
Run Code Online (Sandbox Code Playgroud)

现在要为用户必须调用的成员函数创建函子

UniversalFunctor<ReturnType>::Create<ClassName, ClassFunction>(Object)
Run Code Online (Sandbox Code Playgroud)

这是相当麻烦的。

由于 Object 必须是 ClassName 类型或者至少可以推导出来,我预计会出现这样的调用:

UniversalFunctor<ReturnType>::Create<ClassFunction>(Object)
Run Code Online (Sandbox Code Playgroud)

也应该能够成功,因为 ClassName 参数可以从传递的指针中推导出来。然而,这似乎不可能,因为 ClassFunction 始终被视为第一个模板参数。

eer*_*ika 5

不可以,您只能按声明顺序指定模板参数。因此,您可以指定第一个并推导第二个,但反之则不然。

您可以为模板编写一个包装器:

template<class B, class A>
B function_wrapped(A&& object)
{ 
    return function<A, B>(std::forward<A>(object));
}
Run Code Online (Sandbox Code Playgroud)

现在您可以致电:

function_wrapped<BType>(AInstance);
Run Code Online (Sandbox Code Playgroud)

当然,如果只改变原函数中参数的顺序会更简单。

第二个例子的问题比较多。

如果你可以逆转类型的依赖关系。通过要求B定义一个别名A,那么您可以定义:

template<class B, B foo>
void function(typename B::A object)
Run Code Online (Sandbox Code Playgroud)

并打电话

function<decltype(BInstance), BInstance>(AInstance);
Run Code Online (Sandbox Code Playgroud)

这不是很漂亮。

最简单的解决方案是使用运行时非类型参数,以便可以推导所有类型。

template<class A, class B>
void function(A object, B foo)
Run Code Online (Sandbox Code Playgroud)