Использование функторов с параметрами обычно выглядит так:
// 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));
Для функтора без параметров код может стать
// 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());
но я бы предпочел следующее использование:
std::vector<int> v;
std::find_if(v.begin(), v.end(), some_functor_without_params); // no parens
который имеет следующие преимущества:
some_functor_without_params(i)
скорее, чем some_functor_without_params()(i)
bool some_functor_with_params(int i) {return i == 42;}
Я реализовал это следующим образом в заголовочном файле:
namespace {
struct
{
bool operator ()(int i) const {return i == 42;}
} some_functor_without_params;
}
Я думаю, что структура не нуждается в имени, так как у нее нет объявленного пользователем конструктора (ни деструктора, ни чего-либо, требующего имя структуры). Я поместил объект в безымянное пространство имен, чтобы у каждого модуля компиляции был свой some_functor_without_params
и нет ошибки ссылки «двойное определение».
Есть ли какие-либо потери производительности или другие недостатки, которые я не вижу?
Этот подход работал, как и ожидалось, пока я не столкнулся с очень странной ошибкой компиляции в Visual C ++ 2013, которая исчезла при именовании типа функтора, то есть при замене
struct
{
bool operator ()(int i) const {return i == 42;}
} some_functor_without_params;
с
struct some_functor_without_params_t
{
bool operator ()(int i) const {return i == 42;}
} some_functor_without_params;
Ошибка возникает только в Debug, а не в Release и состояниях
error C2039: '<unnamed-type-some_functor_without_param>': is not a member of 'my_namespace:: ?? A0xbf2cc73f'
в файле xstring
, Вот:
_Myt& operator+=(const _Elem *_Ptr)
{ // append [_Ptr, <null>) // <-- on this line(!)
return (append(_Ptr));
}
Похоже, ошибка компилятора, что вы думаете?
Задача ещё не решена.
Других решений пока нет …