Template functors vs functions - c++

I have been looking at some of the Boost source code and noticed they implement templated functions by using a functor instead of a plain function? Is there a reason for this?
For example:
template<typename Foo, typename Bar>
struct functor {
Bar operator()(const Foo& foo) {
return foo.as_bar();
}
};
as opposed to:
template<typename Foo, typename Bar>
Bar func(const Foo& foo) {
return foo.as_bar();
}
The only advantage I can come up with is it allows classes to inherit the function?

There are two main reasons: The first is, as pythonic metaphor noted, partial specialization is only valid for classes and not functions. Note that functions can use overloads to overcome this problem generally, but often if you are doing metaprogramming it's easier and more generic to use partial specialization. I'd actually think this was the main reason.
The second reason is that anytime that code wants to accept a function object (like in the STL, e.g. std::transform), it will have a type template parameter. If you pass a functor or a lambda, the exact type is known at compile time, and you don't pay for indirection, and inlining can be performed. If you pass a function pointer (or a std::function), only the signature is known at compile time, and you pay for an indirection (and you can't inline). For instance, std::sort can be considerably faster with a functor than a function pointer.
Note that there is a little used feature called function pointer template parameters; these are non type template parameters that specialize on a specific function, and thus can remove indirection. However, if you use one of these, you can't use a functor at all. So most code that wants to accepts a function object does it the way I described above.

Related

How to deal with variable const in templated code?

I have a class myClass that is templated, and I have it in mind to use it for two particular types.
The trouble is that whether or not something should be const in myClass depends on whether it is instantiated with the first type (in which pretty much everything is const) or the second type (in which pretty much everything is non-const).
How do I solve this problem? It seems there are two possible approaches.
I could write const in the templated code as if it were for the first type (the one that actually is const), and then somehow "throw away" all those consts once I instantiate with the second type? Is this possible?
The second approach is to not write const at all, and then when I instantiate myClass with the first type, I make the entire object itself const. This seems to make up a bit for the lack of const-correctness in the class implementation itself...
Or maybe I can do something else?
EDIT: Wait, no, the last approach wouldn't work, as I then wouldn't be able to call non-const methods....
Let's assume you have these two arbitrary types you want to instantiate your template class with, the first of which should trigger constness for your members:
struct RequiresConst
{};
struct OtherStruct
{};
You can then write some convenience templates like this:
template<class T, bool B>
using conditional_const = typename std::conditional<B, const T, T>::type;
template<class T>
constexpr bool needsConst = std::is_same_v<T, RequiresConst>;
This allows you to naturally spell out what you want:
template<class T>
struct MyClass
{
conditional_const<int, needsConst<T>> member;
};
Demo (including test).
Note that this only works for member variables. I'm not aware of a way to make functions const or non-const in a similarly convenient way. But you could write a const and non-const version for each function and enable exactly one of each pair via std::enable_if (or some other SFINAE).
It should also be mentioned that "this member should be const if the template parameter is this exact class" is a pretty odd requirement - not necessarily wrong but smelly. There is probably some specific trait that class has that you should check instead. But maybe your use case really only ever has the template instantiated for those two classes and the above will be sufficient.
Use a type_traits class.
Start with an empty typetraits class, then specialize it for your first type. Place there all the types you need with the const.
Then specialize it again for your second type, and place there the types without const.
Finally, in your templated class, use the type traits with the template type to select the types you need.

Accept all types as argument in function

How can I in C++ make a function accept every Object, so I can give it numbers, String or other Objects. I am not very well in C++, I hope it's not a totally stupid question...
Edit: Ok, an example: if you want to try to wrap the std::cout streams into normal functions, that funtion should be able to accept everything - from Integers over Floats to complex Objects. I hope it's more clear now!
You can overload your function for different types, i.e.
size_t func(int);
size_t func(std::string);
Alternatively and/or additionally, you can provide a function template, which is a way to tell the compiler how to generate your function for any particular type, for example
template<typename T>
size_t func(T const&) { return sizeof(T); }
You may use more advanced techniques such as SFINAE to effectively overload those template functions, i.e. to use different templates for different kind of types T (i.e. integral types, pointer, built-in types, pod, etc). The compiler will then pick the best-fitting func() (if any) for any function call it encounters and, if this is a template, generate an appropriate function.
This requires no re-coding.
A completely different approach is to use a generic erasure type, such as boost::any, when the function will need to resolve the expected types at coding-time (as opposed to compile-time):
size_t func(boost::any const&x)
{
auto i = boost::any_cast<const int*>(x);
if(i) return func(*i);
// etc for other types, but this must be done at coding time!
}
You can use templates for this purpose:
template <typename T>
void foo(T const & value)
{
// value is of some type T, which can be any type at all.
}
What you can actually do with the value may be rather limited without knowing its type -- it depends on the goal of your function. (If someone attempts to call the function with an argument type that causes that function specialization to be ill-formed then your template function will fail to instantiate and it will be a compile-time error.)
I'm not sure what you're trying to accomplish, but you can pass a void pointer as a parameter.
void foo(void* bar);
If I understood you correctly you might wanna try using templates http://en.cppreference.com/w/cpp/language/function_template
You are probably looking for templates.
I suggest you read this.

Generic lambdas Vs Standard template functions (What to use and When)

Generic Lambdas are a way of defining lambdas that read as follows:
auto identity = [](auto a){return a;}
Compare this with:
template <typename T>
T Identity(T t){return t;}
or with
template <typename T>
struct Identity { T operator()(T a) { return a; } };
This is my understanding
lambdas allow context capture using [&], [=], etc, I am not sure how this will be used / applied in generic lambdas. Is this the main difference ?
generic lambdas can be cast to function pointers whereas, template specialisation can be cast to function pointers.
A simple real world example will be useful to understand what to use and when.
[Appended] Here is the generic lambda proposal : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3559.pdf
Pretty much like lambdas, generic lambdas are defined through equivalence to an implicitly defined function object (where non-generic lambdas have the additional ability that with empty capture they can convert to a function pointer). The only real difference between generic and non-generic lambdas is that generic lambda have call operator which is a function template while it is a non-template for non-generic lambdas.
For generic lambdas the conversion to function pointers doesn't exist (see 5.1.2 [expr.prim.lambda] paragraph 6).
Since generic lambdas are still objects with a call operator, they can be used directly as an argument where a generic function objects can be used. That is not the case for a function templates: these behave more like an overload set and you need to get the instantiated before you can pass them as a function object.
Although you can't get a pointer to a function template, you can get a pointer to a function template specialization (as #Columbo pointed out in a comment, a function template specialization is a function). You can't get a pointer to a function out of a generic lambda.
Function templates participate in overload resolution while function objects don't really participate: when an object is found during name look-up this object is chosen even if there could be functions found with the same name and with a nice match for overloading. This implies, that these two are not equivalent:
template <typename T>
auto identity(T value) { return value; }
auto identity = [](auto value) { return value; }
The second implementation hijacks the name while the former is used as a candidate in overload resolution.
Aside from auxiliary objects created from within a function I would use generic lambdas for functions which are not meant as customization points (e.g. it would be nice if standard library algorithms were such objects). The main benefit is that function objects can be readily adapted, e.g., using std::bind() which is not true for function templates.

Templated functor in C . Class template vs Function template

Suppose I want to create a functor that acts upon some general type.
For example
template<typename Ape>
class functor1
{
void operator()(Ape& m)
{
// Do something to m
}
};
This has been the standard way of doing things for me. However, I also have another way:
class functor2
{
template<typename Ape>
void operator()(Ape& m)
{
// Do something to m
}
};
The advantage of the second approach is that I don't have to explicitly state the type of the template.
int main()
{
std::vector<chimpanzee> chimps(100);
for_each(chimps.begin(), chimps.end(), functor1<chimpanzee>()); // Explicity state the type
for_each(chimps.begin(), chimps.end(), functor2()); // Less typing. Will it work?
}
Will the second version work? Or am I missing something? If it works are there any advantages to the first approach?
The obvious difference is that in the first case you specify the type explicitly, and in the second case it is the compiler that will deduce the type for you in the context of the actual call. However, in you specific example it might make no real difference at all.
If your class had multiple member functions in it, the first variant would "fix" the same template parameter for all of them, while in the second variant the parameter would be deduced for each member function independently.
The same is true when a single member function is called from multiple contexts: each context will perform its own template argument deduction in the second variant.
It could be good or not so good, depending on your intent.
If your function accepted its argument by value (or by const reference), in the first variant you could specify a different type for the argument than the one stored in the container. For example, you could have created a functor for long and applied it to the container of ints. This is not possible in the second variant.
For example, if your chimpanzee class was polymorphic, derived from animal, you could have used a functor1<animal> to iterate over such container. In the second variant the template parameter will be deduced for you as chimpanzee, not as animal.
If your class had data members, the second variant would make sure that all specializations of member function(s) share the same data, if the same functor object is used. In the first variant each specialization is a different class, it gets its own data.
For functors with no state this should be the same. Frequently (compares) you need to store another object/ref/pointer of the same type in the functor and your second option wouldn't work in that case. Note that if your functor does need constructor parameters you can make a free function make_<foo> like make_pair to deduce the type for you and again reduce typing.
It's like scoping: in functor1, anything in the class can use the type Ape (for member declarations, parameter and return types types, traits, or whatever), while in functor2, Ape only means something within the scope of operator(). In short:
Time of definition:
functor1 needs to know about Ape when it is created.
functor2 doesn't need to know about Ape until it is called.
Scope of type:
Everything in functor1 knows about Ape.
Only operator() in functor2 knows about Ape.
Versatility of an instance:
A functor1 instance only works with a single type of Ape.
A functor2 instance works with any type of Ape.

Why doesn't unary_function define operator()?

I was just looking for a handy base class for a set of functors to be based on taking and int and returning void.
Thinking to use std/functional the functors are basically going to be unary_function<int,void> with operator().
Why is virtual result_type operator()(const argument_type& _Left) const = 0; not defined on the unary_function template? I'm guessing that it's because there could be variations in constness...
Is there some other template I've missed that includes the operator()?
I haven't done this in a while, am I missing something?
How would I also make use of existing functional like
std::ptr_fun< HWND, void >(someFunction);
std::pointer_to_unary_function<HWND, void>(someFunction);
EDIT:
Perhaps I should include the other half of the usage to make this complete. Maybe it's the usage half that is not fitting in with the concept.
How would one pass the functor to a method and use it?
typedef unary_function<int,void> Functor;
void DoStuff(const Functor& functor) {
int demo = 1;
functor(demo);
}
functor as a unary_function doesn't define operator() and so DoStuff doesn't compile.
Template concepts are duck-typed. The fact that a class satisfying the UnaryFunction concept needs operator() is specified in the documentation and inferred from the templates which use template parameters satisfying that concept. There's no need to spell out the function signature, or to require that it be virtual, that it take a const reference parameter, or that it be a const member function.
The unary_function template should not be thought of as an interface (and it isn't designed as one). It's certainly not a polymorphic base class. It's a helper, which is used by classes that wish to implement the AdaptableUnaryFunction concept.
From the STL docs, which are reliable for the original design rationale: "the only reason it exists is to make defining Adaptable Unary Functions more convenient" - http://www.sgi.com/tech/stl/unary_function.html
The standard is similar: "The following classes are provided to simplify the typedefs of the argument and result types" (20.3.1/1)
Advanced usage - actually what's required for UnaryFunction is that if f is a unary function object, and x is convertible to the argument type, then f(x) is a valid expression of the result type. It needn't have a one-argument operator() at all, it's fine to have a two-arg operator() with the second arg having a default value. Try defining that as a pure virtual function ;-)
Second question, you make use of ptr_fun just by calling it with function name/pointer. Its template parameters will be inferred from the function type, so you don't need to specify them. The result is an object of the corresponding pointer_to_unary_function template type.
To use the example straight from the STL docs:
transform(first, last, first,
compose1(negate<double>, ptr_fun(fabs)));
This is approximately equivalent to:
for (auto current = first; current != last; ++current) {
*current = -fabs(*current);
}
(where I use auto in its C++0x sense, meaning "I cannot be bothered / it is impossible to write the iterator type here")
A function name/pointer can be used in transform (which takes a UnaryFunction template parameter), but not in compose1 (which takes an AdapatableUnaryFunction template parameter). So without ptr_fun, there's no way to compose negate with fabs.
In response to your Edit, I stress, unary_function is not a polymorphic base class. You cannot usefully use it (or any of its instantiations) as a function parameter type.
If you want to use the UnaryFunction or AdaptableUnaryFunction concepts, then you must write a function template:
template <typename UnaryFunction>
void DoStuff(UnaryFunction &functor) {
int demo = 1;
functor(demo);
}
This only requires that the functor take a type which int converts to, though. It doesn't require that it take exactly int and return exactly void. That's usually an advantage.
If a template doesn't do what you want, then unary_function is not for you. You haven't missed anything: you can design your own interface with a virtual operator(), but the standard libraries don't aim to provide any such thing.
Because a virtual operator () is not a part of the unary_function concept. The unary function concept can have a non-virtual operator in addition to differences in constness.