I want to write a function in c++ that takes a variable of type int and what it does is that it will define the overloading operator () of a functor and will return that functor as output argument. For example:
template<class Functor>
Functor myFunc(double n)
{
Functor f;
double Functor::operator() (double q)
{ return n*q;}
return Functor;
}
class myClass
{
double operator() ( double q ) const ;
};
Is this proper the way of doing it ?
There's a syntactic sugar for what you're trying to do (wrongly). It's called lambda expressions and this is what it should look like:
auto myFunc(double n)
{
return [n](double q) { return n * q; }
}
If C++11 is not available, you can emulate it like this (which fixes your errors above):
class Functor
{
double m_n;
public:
Functor(double n) : m_n(n) {}
double operator()(double q) const { return m_n * q; }
};
Functor myFunc(double n)
{
return Functor(n);
}
If you wish, you can keep myFunc as a template, but the point is, you can change the behaviour by the functor you pass in, so trying to hardcode operator() inside myFunc does not really make sense, and is not possible.
Making it more generic:
template <typename T>
class Functor
{
T m_n;
public:
Functor(T n) : m_n(n) {}
T operator()(T q) const { return m_n * q; }
};
template <template <typename> class Functor, typename T>
auto myFunc(T n)
{
// we can use perfect forwarding here, but it's far beyond the original question
return Functor<T>(n);
}
Usage:
myFunc<Functor>(2)(3)
Even more generic, for variable amount of parameters captured by a functor (variadic templates):
template <template <typename ...> class Functor, typename ... Ts>
auto myFunc(Ts ... ns)
{
return Functor<Ts...>(ns...);
}
Related
I am writing an identity function for some of my classes that keeps a count of its calls (long story -> short: metrics).
At the moment, I'm trying to figure the performance differences/benefits of using a template vs auto.
Here is a short example taken from my code of what I'm doing:
namespace Metrics {
unsigned long identifications = 0;
//auto version
auto identity(auto i) {
//... other stuffs
identifications++;
return i;
};
//template version
template<class I> I identity(I i) {
//... other stuffs
identifications++;
return i;
};
};
There's a bit more going on, but that is the basics. I know the compiler will just make a function for each, i.e.
identity(5);
identity("5");
//generates the functions
int identity(int i) { ... return i; };
const char* identity(const char* i) { ... return i; };
At run-time, which one is faster?
And do they have a compile time difference?
Since this function is meant to be called a lot, I'm more interested in run-time performance, but there also could be a large amount of types to generate the function for, so I'm also interested in which one would be faster at compile-time.
auto identity(auto i)
{
//...
return i;
}
is a shorthand for
template <class T>
auto identity(T i)
{
// ...
return i;
}
which in turn is a shorthand for
template <class T>
T identity(T i)
{
// ...
return i;
}
So no difference whatsoever.
Not applicable to your example, but if you are going to use auto parameters you need to be aware of some gotchas:
auto as return type
auto foo(auto a)
Does not mean
// not this
template <class T>
T foo(T a)
The return type will be deduced from the return expression(s) in foo definition, just like any auto return type. It just happens that in your function the return type is deduced to be the same as the parameter type.
Multiple auto parameters
void foo(auto a, auto b)
Is not equivalent to
// not this
template <class T>
void foo(T a, T b)
but with
template <class T, class U>
void foo(T a, U b)
I am writing an identity function for some of my classes that keeps a count of its calls (long story -> short: metrics).
At the moment, I'm trying to figure the performance differences/benefits of using a template vs auto.
Here is a short example taken from my code of what I'm doing:
namespace Metrics {
unsigned long identifications = 0;
//auto version
auto identity(auto i) {
//... other stuffs
identifications++;
return i;
};
//template version
template<class I> I identity(I i) {
//... other stuffs
identifications++;
return i;
};
};
There's a bit more going on, but that is the basics. I know the compiler will just make a function for each, i.e.
identity(5);
identity("5");
//generates the functions
int identity(int i) { ... return i; };
const char* identity(const char* i) { ... return i; };
At run-time, which one is faster?
And do they have a compile time difference?
Since this function is meant to be called a lot, I'm more interested in run-time performance, but there also could be a large amount of types to generate the function for, so I'm also interested in which one would be faster at compile-time.
auto identity(auto i)
{
//...
return i;
}
is a shorthand for
template <class T>
auto identity(T i)
{
// ...
return i;
}
which in turn is a shorthand for
template <class T>
T identity(T i)
{
// ...
return i;
}
So no difference whatsoever.
Not applicable to your example, but if you are going to use auto parameters you need to be aware of some gotchas:
auto as return type
auto foo(auto a)
Does not mean
// not this
template <class T>
T foo(T a)
The return type will be deduced from the return expression(s) in foo definition, just like any auto return type. It just happens that in your function the return type is deduced to be the same as the parameter type.
Multiple auto parameters
void foo(auto a, auto b)
Is not equivalent to
// not this
template <class T>
void foo(T a, T b)
but with
template <class T, class U>
void foo(T a, U b)
I have an exercise where I need to write a function. Function scheme look like
auto add(int a){
}
I need to be able to call this function with many brackets:
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10
add(1)(2)(3)(4)(5); // 15
But I can not figure out which C++ feature I should use in this case. I heard that I should use functors but I don't know if this is the best idea in this case.
You can do it by having add return a functor, i.e., an object that implements operator(). You can write a templated version that will let the compiler deduce the type. Try it here.
template <class T>
struct adder
{
T val;
adder(T a) : val(a) {}
template <class T2>
auto operator()(T2 a) -> adder<decltype(val + a)> { return val + a; }
operator T() const { return val; }
};
template <class T>
adder<T> add(T a)
{
return a;
}
Example
In this example, T will ultimately resolve to double:
std::cout << add(1)(2.5)(3.1f)(4) << std::endl;
// T is int -----^
// T is double ------^
// T is still double -----^
// T is still double ----------^
Here is another example where T will resolve to double:
std::cout << add(1)(2.5f)(3.1)(4) << std::endl;
// T is int -----^
// T is float -------^
// T is double ------------^
// T is still double ----------^
Explicit Constructor
If you want the constructor of adder to be explicit you also have to change the return statements slightly.
template <class T>
struct adder
{
T val;
explicit adder(T a) : val(a) {}
template <class T2>
auto operator()(T2 a) -> adder<decltype(val + a)>
{
return adder<decltype(val + a)>(val + a);
}
operator T() const { return val; }
};
template <class T>
adder<T> add(T a)
{
return adder<T>(a);
}
The only solution that comes to my head is make this "add" as some class object with overloaded brackets operator, which will return new object, and then call new brackets from it, but you will need to return final value from it somehow, like some getter func.
class Adder{
private:
int value;
public:
Adder():value(0){}
Adder(int a):value(a){}
int get(){return value;}
Adder operator() (int a) {
return Adder(value+a);
}
};
But it doesn't seem as something useful, probably there is better way to accomplish what you want to get.
I have a problem compiling this code.
All I am trying to do is create a variadic class template that can give me the sum of all elements that are passed in (eg. 1,2,3,4,5,6 should give 21) whether it's int or float. I could basically do it with two function templates recursively for which I'm getting the answer correctly but when I'm implementing it in class it doesn't give me an answer.
template <typename T>
class Myclass
{
public:
T sum;
T func(T A,T... B)
{
sum+=A;
func(B...);
}
T func(T A)
{
sum+=A;
return sum;
}
};
int main()
{
Myclass<int> myclass;
cout<<myclass.func(12,11,11,23);
return 0;
}
Your code does not compile because T... is an invalid variadic expansion, as T is not a parameter pack.
You code has also several other issues. I will address them in the snippet below:
template <typename T>
class Myclass
{
public:
// `sum` needs to be initialized to a value, otherwise its value
// will be undefined.
T sum = 0;
// `TRest...` is a template variadic type pack.
template <typename... TRest>
T func(T A, TRest... B)
{
sum+=A;
// You need to return from the recursive case of `func`.
return func(B...);
}
T func(T A)
{
sum+=A;
return sum;
}
};
working wandbox example
Note that the values matched in TRest... can be of any type. If you want to force them to be T, you can use the following technique (or static_assert):
template <typename...>
using force_to_t = T;
// ...
T func(T A, force_to_t<TRest>... B)
{
sum+=A;
// You need to return from the recursive case of `func`.
return func(B...);
}
I learned this solution thanks to Piotr's answer on another question.
T func(T A,T... B)
{
sum+=A;
func(B...);
}
This is not valid C++ syntax when func is not a function template with T its template parameter pack. ... can only be used to expand packs; T is a non-pack template parameter of the class template.
There are two ways to do this, depending on what you want to achieve.
One: If you want func to accept a mix of arbitrary types, you can make it a (member) function template:
template <typename T>
class Myclass
{
public:
T sum;
template <class F1, class... F>
T func(F1 A, F... B)
{
sum+=A;
func(B...);
return sum;
}
template <class F>
T func(F A)
{
sum+=A;
return sum;
}
};
Two: If you want func to only accept Ts, you can change it to use an initializer list:
template <typename T>
class Myclass
{
public:
T sum;
T func(std::initializer_list<T> A)
{
for (const auto& a : A)
sum+=a;
return sum;
}
};
Note that this will require calling it with a list in braces (e.g. func({1, 2, 42}) instead of func(1, 2, 42), but it's the approach also taken by e.g. std::max.
Notice that there are a few issues in your code unrelated to the question at hand.
One, which I fixed in the example above, is that your first overload of func didn't return anything. Calling it would result in Undefined Behaviour.
Another one, pointed out by #Zereges in the comments, is that T sum is not initialised explicitly. If MyClass is instantiated with a POD type (such as int or double), it will be used uninitialised. You should add a constructor for Myclass:
Myclass() : sum{} {}
You can avoid the need for recursive calls by writing the sequential sum+=A as an initialiser for a std::initializer_list:
template <typename T>
class Myclass
{
template <class... F>
T func_impl(F... A)
{
std::initializer_list<int>{
((void)(sum+=A), 0)...};
return sum;
}
public:
Myclass() :sum(){}
T sum;
template <class F1, class... F>
T func(F1 A, F... B)
{
return func_impl(A, B...);
}
};
You can do that with another approach that avoid recursive call.
template <typename T>
class Myclass
{
public:
T sum;
Myclass() { sum = 0; }
template<typename ...T1>
T func(T1 ... args)
{
auto l_expansion_list =
{
(
[this, &args]()
{
this->sum += args;
return true;
}()
)...
};
return sum;
}
};
Say I want a C++ function to perform arithmetic on two inputs, treating them as a given type:
pseudo:
function(var X,var Y,function OP)
{
if(something)
return OP<int>(X,Y);
else if(something else)
return OP<double>(X,Y);
else
return OP<string>(X,Y);
}
functions that fit OP might be like:
template <class T> add(var X,var Y)
{
return (T)X + (T)Y; //X, Y are of a type with overloaded operators
}
So, the question is what would the signature for function look like? If the operator functions are non-templated I can do it, but I get confused with this extra complexity.
Template functions cannot be passed as template arguments. You have to manually deduce template arguments for this function before you pass it to another template function. For example, you have function
T sum(T a, T b)
{
return a + b;
}
You want to pass it to callFunc:
template<typename F, typename T>
T callFunc(T a, T b, F f)
{
return f(a, b);
}
You can't simply write
int a = callFunc(1, 2, sum);
You have to write
int a = callFunc(1, 2, sum<int>);
To be able to pass sum without writing int, you have to write a functor - struct or class with operator() that will call your template function. Then you can pass this functor as template argument. Here is an example.
template<class T>
T sum(T a, T b)
{
return a + b;
}
template<class T>
struct Summator
{
T operator()(T a, T b)
{
return sum<T>(a, b);
}
};
template<template<typename> class TFunctor, class T>
T doSomething(T a, T b)
{
return TFunctor<T>()(a, b);
//Equivalent to this:
//TFunctor<T> functor;
//return functor(a, b);
}
int main()
{
int n1 = 1;
int n2 = 2;
int n3 = doSomething<Summator>(n1, n2); //n3 == 3
return 0;
}
Are you looking for this?
template<class T> T add(T X, T Y)
{
return X + Y;
}
Or are you looking for something that calls something like add?
template<class T, class F>
T Apply(T x, T y, F f)
{
return f( x, y );
}
Called via:
int x = Apply( 2, 4, add<int> );
I'm a bit confused … why the type differentiation in your pseudo-code?
C++ templates allow full type deduction on templates:
template <typename T, typename F>
T function(T x, T y, F op) {
return op(x, y);
}
Here, F fits anything (especially functions) that may be called with the () function call syntax and accepting exactly two arguments of type T (or implicitly convertible to it).
I use lambdas for this.
auto add = [](const auto& lhs, const auto& rhs) {
static_assert(std::is_arithmetic<typename std::decay<decltype(lhs)>::type>::value,
"Needs to be arithmetic.");
static_assert(std::is_arithmetic<typename std::decay<decltype(rhs)>::type>::value,
"Needs to be arithmetic.");
return lhs + rhs;
};
template<typename LHS, typename RHS, typename FUNC
, typename OUT = typename std::result_of<FUNC(LHS, RHS)>::type>
constexpr OUT do_arithmetic(LHS lhs, RHS rhs, FUNC func) {
return func(lhs, rhs);
}
constexpr auto t = do_arithmetic(40, 2, add);
static_assert(t == 42, "Wrong answer!");
static_assert(std::is_same<std::decay<decltype(t)>::type, int>::value,
"Should be int.");
template <class OP> void function(OP op)
{
// call with int
op(1, 2);
// or with double
op(1.2, 2.3);
// call with explicit template argument
op.template operator()<int>(1, 2);
op.template operator()<string>("one", "two");
}
struct Add
{
template <class T> T operator ()(T a, T b)
{
return a + b;
}
};
function(Add());
// or call with C++14 lambda
function([](auto a, auto b) { return a + b; });
I think you're looking for the Strategy Pattern.
I'm not sure what this var thing in your question means. It's certainly not a valid C++ keyword, so I assume it's a type akin to boost:any. Also, the function is missing a result type. I added another var, whatever that might be. The your solution could look like this:
template< template<typename> class Func >
var function(var X, var Y, Func OP)
{
if(something)
return OP<int>(X,Y);
else if(something else)
return OP<double>(X,Y);
else
return OP<string>(X,Y);
}
The funny template argument is a template itself, hence its name "template template argument". You pass in the name of a template, not an instance. That is, you pass std::plus, not std::plus<int>:
return function( a, b, std::plus );