First my question and then an explanation of what I'm trying to do as I might be approaching the problem wrong.
Is it possible to deduce the first template parameter in a multi parameter template from parameters while specifying the other parameters.
Example:
template<class A, class B>
B function(A object)
{
return B(A);
}
called like:
function<BType>(AInstance);
I could not find a way to make this work.
EDIT: Another example might fit better to my problem below as indicated to me by the first comment I got
Example:
template<class A, A::B foo>
void function(A object)
{
object.doSomethingWithTypeA::B(foo);
}
called like:
function<A::BInstance>(AInstance);
The difference is that the second template parameter is dependent on the specific type of the first so I can not switch the template parameters around.
Now for a description of what I am trying to do:
I am currently trying to create a templates universal functor class that can take either a free function or a member function and wrap it into a functor.
I succeeded in what I set out to do but now I want to make everything just a bit more user friendly. Currently the templated function to create a functor looks like:
template <class T, ReturnType (T::*Method)(FunctionArguments...)>
static constexpr UniversalFunctor Create(T* object) {
return {object, MethodWrapper<T, Method>};
}
Right now to create a functor for a member function a user has to call
UniversalFunctor<ReturnType>::Create<ClassName, ClassFunction>(Object)
which is rather cumbersome.
Since Object has to be of type ClassName or at least be deducible to this I would have expected that a call like:
UniversalFunctor<ReturnType>::Create<ClassFunction>(Object)
should also be able to succeed as the ClassName parameter is deducible from the pointer passed. However that does not appear to be possible as ClassFunction is always treated as the first template parameter.
Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.
Multiple parameters can be used in both class and function template. Template functions can also be overloaded. We can also use nontype arguments such as built-in or derived data types as template arguments.
Can there be more than one argument to templates? Yes, like normal parameters, we can pass more than one data type as arguments to templates.
Class Template Argument Deduction (CTAD) is a C++17 Core Language feature that reduces code verbosity. C++17's Standard Library also supports CTAD, so after upgrading your toolset, you can take advantage of this new feature when using STL types like std::pair and std::vector.
No, you can only specify template arguments in order of declaration. So, you can specify the first and let second be deduced, but not the other way around.
You could write a wrapper for template:
template<class B, class A>
B function_wrapped(A&& object)
{
return function<A, B>(std::forward<A>(object));
}
Now you can call:
function_wrapped<BType>(AInstance);
Of course, it would be simpler to just change the order of the parameters in the original function.
The second example is quite a bit more problematic.
If you can reverse the dependency of the types. By requiring that B
defines an alias to A
, then you could define:
template<class B, B foo>
void function(typename B::A object)
And call
function<decltype(BInstance), BInstance>(AInstance);
It's not very pretty.
The simplest solution would be to use runtime non-type arguments so that all types can be deduced.
template<class A, class B>
void function(A object, B foo)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With