Using functors with parameters generally looks like that:
// Definition:
struct some_functor_with_params
{
int ref;
explicit some_functor_with_params(int ref) : ref(ref) {}
bool operator ()(int i) const {return i == ref;}
};
// Usage:
std::vector<int> v;
std::find_if(v.begin(), v.end(), some_functor_with_params(42));
For a functor without parameters, the code may become
// Definition:
struct some_functor_without_params
{
bool operator ()(int i) const {return i == 42;}
};
// Usage:
std::vector<int> v;
std::find_if(v.begin(), v.end(), some_functor_without_params());
but I would prefer the following usage:
std::vector<int> v;
std::find_if(v.begin(), v.end(), some_functor_without_params); // no parens
which has the following advantages:
- more concise
- more readable when invoking the functor directly:
some_functor_without_params(i)
rather thansome_functor_without_params()(i)
- interchangeable with a function:
bool some_functor_with_params(int i) {return i == 42;}
I implemented it the following way in a header file:
namespace {
struct
{
bool operator ()(int i) const {return i == 42;}
} some_functor_without_params;
}
I think the struct does not need a name since it has no user-declared constructor (nor destructor, nor anything requiring the struct name). I put the object in an unnamed namespace so that each compilation unit has its own some_functor_without_params
and there is no 'double definition' link error.
Is there any performance penalty or any other drawback I cannot see?
This approach worked as expected until I encountered a very strange compilation error with Visual C++ 2013 which disappeared when naming the functor type, i.e. replacing
struct
{
bool operator ()(int i) const {return i == 42;}
} some_functor_without_params;
with
struct some_functor_without_params_t
{
bool operator ()(int i) const {return i == 42;}
} some_functor_without_params;
The error occurs only in Debug, not in Release, and states
error C2039: '<unnamed-type-some_functor_without_param>': is not a member of 'my_namespace:: ?? A0xbf2cc73f'
in file xstring
, here:
_Myt& operator+=(const _Elem *_Ptr)
{ // append [_Ptr, <null>) // <-- on this line(!)
return (append(_Ptr));
}
It looks like a compiler bug, what do you think?