Is it possible to use using for functions? - c++

For example
template<class T, class U>
void f();
template<class T> using g = f<T, int>;
Or any similar idea for functions?

No. You cannot do that. You need to create a new function that calls f, forwarding all arguments and template arguments.
template<class T, class U>
void f();
template<class T>
void g() {
f<T, int>();
}
A C++14 alternative is a variable template of function pointer type:
template<typename T>
void (*g)() = &f<T, int>;
Although this approach ignores default arguments and probably has other quirks as well. I highly recommend the more verbose wrapping approach.

No, you can not do that as templated aliases are used to create aliases of types, not concrete data.
What you are trying to do is to create an alias/type from the address of a function as f<T, int> decays into a pointer to function.
You can however create a templated alias from the type of the function f.
template <typename T>
using g = typename std::add_pointer<decltype(f<T, int>)>::type;
int main() {
// Type of 'func' is 'void (*)()' with template arguments '{T1=double, T2=int}'.
g<double> func;
func = f<double, int>; // Point to function with same signature and template args.
func(); // Ok to call function.
}

Related

how to get a return type of a member function pointer

Is there a way to determine a return type of a member function pointer?
Code sample:
///// my library
void my_func(auto mptr) { // have to use `auto`
// some logic based on a return type of mptr: int, string, A, etc.
}
///// client code
struct A {
int foo();
std::string bar(int);
};
class B{
public:
A func(int, double);
};
// ... and many other classes
my_func(&A::foo);
my_func(&A::bar);
my_func(&B::func);
// ... many other calls of my_func()
I need to "fill in" my_func().
Edit:
I can't use std::result_of/std::invoke_result as I don't know the full list of parameters of mptr. It's not important with which params a method is supposed to be called as I'm not calling it. I would like to avoid creating an object of base class of mptr even if I'm able to determine it (using declval is ok).
You can use partial template specialization to determine the return type of mptr:
template <typename T>
struct ReturnType;
template <typename Object, typename Return, typename... Args>
struct ReturnType<Return (Object::*)(Args...)>
{
using Type = Return;
};
void my_func(auto mptr) {
typename ReturnType<decltype(mptr)>::Type obj;
}
Live Demo
You can write a function that deduces the type of a member function pointer, and returns the deduced return type. Note that only a declaration, and no definition is needed
template <typename C, typename Ret, typename... Args>
auto ret_type(Ret (C::*)(Args...)) -> Ret;
void my_func(auto mptr)
{
using type = decltype(ret_type(mptr));
}
In my opinion, this is also easier to read than the specialization solution.
Here's a demo
You can also account for cv-qualifiers by adding overloads. e.g.
template <typename C, typename Ret, typename... Args>
auto ret_type(Ret (C::*)(Args...) const) -> Ret;
Here's a demo

How to typedef template function pointer?

I want to typedef a function pointer that points to a template function.
class A
{
template <typename T>
typedef void (*FPTR)<T>();
}
I have tried in this way and didn't succeed. Any idea about this thing?
As #HolyBlackCat pointed out, the normal function pointer should work as you have a simple templated void function, whose template parameter does not act on both return and argument types.
template <typename T>
void someVoidFunction() {}
using fPtrType = void(*)();
int main()
{
fPtrType funPtr1 = &someVoidFunction<int>;
fPtrType funPtr2 = &someVoidFunction<float>;
fPtrType funPtr3 = &someVoidFunction<std::string>;
return 0;
}
If it was the case, that template parameters depends on the function arg and return types you should have instantiated the function pointer as well for each kind.
template <typename T, typename U>
T someFunction(U u) {}
template <typename T, typename U>
using fPtrType = T(*)(U);
int main()
{
fPtrType<int, float> funPtr1 = &someFunction<int, float>; // instance 1
fPtrType<float, float> funPtr2 = &someFunction<float, float>; // instance 2
return 0;
}
Template functions produce functions. Template classes produce classes. Template variables produce variables.
Pointers can point at functions or variables. They cannot point at templates; templates have no address.
Typedef defines the type of a variable.
A template variable pointer could collectively point at various instances of a template function, but the initial binding would be done at compile time, and could only be aimed somewhere else one variable at a time.

Returning pointer-to-member-function (without typedefs)

Compiling on C++03, I've attempted to write up a test template function that returns a pointer-to-member-function of a member function that returns int, and takes two float arguments:
template<typename TemplateClass>
int (TemplateClass::*)(float,float) Testtest(TemplateClass &A)
{
return &TemplateClass::Function;
}
But naturally, no matter what variations on the pointer-to-member-function syntax I use, the compiler complains of initialisation errors. Typedef, although it works with known classes, for obvious reasons (naming conflicts), won't accept template class arguments for classes that I can't know ahead of time which are likely to use the same function.
What non-typedef way is there to get this function to compile and return a pointer-to-member-function?
To declare it without a type alias, without type deduction, and without a trailing return type:
template<typename TemplateClass>
int (TemplateClass::* Testtest(TemplateClass &A))(float,float)
But of course this isn't what you would use in real code. Instead you would use an alias template:
template<typename T>
using return_type = int (T::*)(float,float);
template<typename TemplateClass>
return_type<TemplateClass> Testtest(TemplateClass &A)
Or return type deduction in C++14:
template<typename TemplateClass>
auto Testtest(TemplateClass &A)
Or a trailing return type (in C++11):
template<typename TemplateClass>
auto Testtest(TemplateClass &A) -> int (TemplateClass::*)(float,float)
You need this prototype:
template<typename TemplateClass>
int (TemplateClass::*Testtest(TemplateClass &A)) (float,float) { }
int (Class::*f())(float,float);
f is function taking no arguments returning pointer to member function of class Class takinf 2 floats and returning int.
And template version:
template <typename Type>
int (Type::*f())(float,float);
I reject the premise of your question. Use typedefs. Or, specifically, a type trait:
template <class T, class F>
struct make_mem_fun {
typedef F T::*type;
};
template<typename TemplateClass>
typename make_mem_fun<TemplateClass, int(float, float)>::type
Testtest(TemplateClass &A)
{
return &TemplateClass::Function;
}
That is way easier to understand than the convoluted syntax of actually returning the type. With C++11, we can turn that into an alias to drop the typename ::type stuff.

difference between C++ template partial specialization for function and functor

I have been using C++ template class partial specialization for function argument for a while. I was surprised to find that the same syntax could be used to partial specialize functors.
In the case 1 below, it is easy to see F(T) is a function type. Since it is a type, it could be used to substitute the template parameter, however in case 2, the semantics of F(T) is changed, it is not a type but still can pass the compiler and work.
I googled a few hours, but not found too much valuable info in this regard. Could anyone explain why case 2 worked?
template<class> struct func;
template<class F, class T>
struct func<F(T)> //1. this is a partial specialization for function
{ //with signature F(T)
using type = F(T);
};
template<class> struct ftor;
template<class F, class T>
struct ftor<F(T)> //2. Is F(T) a type?
{
using type = F;
};
struct foo {
void operator()(int) {}
};
int main() {
//1 void(int) is a function signature
cout<<typeid(typename func<void(int)>::type).name()<<endl;
//2 what is foo(int)?
cout<<typeid(typename ftor<foo(int)>::type).name()<<endl;
return 0;
}
In the 2 cases, F(T) is a signature of function taking T and returning F.
You may rename your class func by identity and ftor by result_of and F by ReturnType to better match naming/implementation.

Why can't C++ infer the template type?

Why can't the compiler figure out these template parameters? Is there a way to make it do so?
(I'm using Visual Studio 2010.)
template<typename T, typename TFunc>
void call(TFunc func) { func(T()); }
void myfunc(void *) { }
int main() { call(myfunc); }
T appears nowhere in the parameter list so T cannot be deduced from the function arguments. All types to be deduced must appear in deduced contexts in the parameter list. For example,
template <typename TReturn, typename TParameter>
void call(TReturn (*f)(TParameter))
{
f(TParameter());
}
Template parameter deduction for function templates only works based on function arguments, nothing else. The function definition is never looked at for the purpose of determining the template parameters, so your parameter T cannot possibly be deduced.
You could remedy your situation by incorporating the type into the function signature: Since you expect the outer function to be called with a function itself, make that explicit:
template <typename T> void foo(void(*f)(T))
{
T x;
f(x);
// ...
}
Combine function overloading with functors, and it becomes impossible in the general case to determine what arguments can be passed to a callable entity.
Consider, for example
struct FunctorExample {
void operator()(int x) {...}
std::string operator()(const std::string& ) {...}
};
If there were some way to coax the compiler to pattern match on arguments, it would have to have undefined or error behavior when applied to FunctorExample.
Instead, the trend seems to be that when you want to template metaprogram with functors, you specify the functor and argument list. Examples (off the top of my head) being boost::result_of and boost::fusion.
Edit: That said, if you're willing to restrict your attention somewhat, and you can use some C++11 syntax (decltype), you can arrange to introspect a bit more:
// Support functors with a very simple operator():
template <typename T> struct argument :
public argument<decltype(&T::operator())> {};
// Pointers to member functions
template <typename C, typename R, typename A> struct argument<R(C::*)(A)>
{typedef A type;};
// Function types
template <typename R, typename A> struct argument<R(A)> {typedef A type;};
// Function pointer types.
template <typename R, typename A> struct argument<R(*)(A)> {typedef A type;};
// Now for call:
template <typename FuncType>
void call(FuncType func) {
typedef typename argument<FuncType>::type Arg;
func(Arg());
}
// example:
class FunctorInt {public: int operator()(int ) {return 0;};};
void myfunc(void *) {}
int main() {
call(myfunc);
call(FunctorInt());
}
Variadic templates could be used to expand this stuff to support more than one argument.