Подтвердить что ты не робот

Можно ли получить указатель на функцию встроенного стандартного оператора?

Я хочу обратиться к указателям на функции встроенных операторов, но я не знаю, как указать конкретные перегрузки типов.

У меня есть следующая подпись класса шаблона:

template<typename ParamsType, typename FnCompareType>
class MyAction
{
public:
    MyAction(ParamsType& arg0, ParamsType& arg1, FnCompareType& fnCpmpare) 
    : arg0_(arg0), arg1_(arg1), fnCompare_(fnCpmpare) {}

    bool operator()()
    {
        if((*fnCompare_)(arg0_,arg1_)
        {
            // do this
        }
        else
        {
            // do s.th. else
        }
    }

private:
    ParamsType& arg0_;
    ParamsType& arg1_;
    FnCompareType& fnCompare_;
}

И хочу использовать синтаксис, подобный этому:

void doConditional(int param1, int param2)
{
    MyAction<int,&::operator>=> action(param1,param2);
    if(action())
    {
        // Do this
    }
    else
    {
        // Do that
    }
}

Но это не скомпилировано:

error: ‘::operator>=’ has not been declared

Что я могу сделать, чтобы ссылаться на такие встроенные статические операции?

4b9b3361

Ответ 1

Встроенные операторы

Почему у вас не может быть указателей на них:

С++ 11, §13.6/1, [over.built]

Функции оператора-кандидата, представляющие встроенные операторы, определенные в разделе 5, указаны в этом подпункте. Эти функции-кандидаты участвуют в процессе обработки перегрузки оператора, как описано в 13.3.1.2 , и используются для других целей.

Встроенные операторы (для встроенных типов) не являются реальными функциями оператора. Поэтому у вас не может быть указателя на функцию, указывающего на них. Вы также не можете вызывать их с помощью синтаксиса operator<(A,B). Они участвуют только в разрешении перегрузки, но компилятор переводит их непосредственно в соответствующую инструкцию asm/machine без какого-либо "вызова функции".

Способ решения этой проблемы:

user1034749 уже ответил на этот вопрос, но для полноты:

Стандарт определяет множество объектов функций в §20.8, [function.objects], т.е.

  • Арифметические операции
  • Сравнения
  • Логические операции
  • Побитовые операции

Функциональный объект является объектом типа объекта функции. В тех местах, где можно было бы ожидать перехода указателя на функцию к алгоритмическому шаблону (раздел 25), интерфейс указан для принятия объекта функции. Это не только позволяет алгоритмическим шаблонам работать с указателями на функции, но также позволяет им работать с произвольными объектами функции.

С++ 11, §20.8.5, [сравнения]

  • equal_to
  • not_equal_to
  • больше, меньше
  • greater_equal
  • less_equal

Это те шаблонные функциональные объекты, которые распадаются на аналогичный оператор в их функции operator(). Они могут использоваться как аргументы указателя функции.

user1034749 прав, я хочу заявить: Нет другого способа, они полностью эквивалентны в использовании для "сырых" указателей на функции. Ссылка приведена.

Операторы класса стандартного класса

Вы можете использовать стандартные библиотечные операторы в качестве указателей функций (которые присутствуют как "реальные функции" ).

Но вам нужно будет обратиться к соответствующему экземпляру шаблона. Компилятору потребуются соответствующие подсказки для вывода правильного шаблона.

Это работает для меня на MSVC 2012, используя operator+ of std::basic_string

template<class Test>
Test test_function (Test const &a, Test const &b, Test (*FPtr)(Test const &, Test const &))
{
   return FPtr(a, b);
}

int main(int argc, char* argv[])
{
   typedef std::char_traits<char> traits_t;
   typedef std::allocator<char> alloc_t;
   std::basic_string<char, traits_t, alloc_t> a("test"), b("test2");
   std::cout << test_function<std::basic_string<char, traits_t, alloc_t>>(a, b, &std::operator+) << std::endl;
   return 0;
}

Если аргумент шаблона test_function не учитывается, это приведет к сбою (по крайней мере, для MSVC 2012).

Ответ 2

Вы можете использовать то же решение, что и в стандартной библиотеке С++:

std::sort (numbers, numbers+5, std::greater<int>());

где больше

template <class T> struct greater : binary_function <T,T,bool> {
    bool operator() (const T& x, const T& y) const {return x>y;}
};

в вашем случае http://www.cplusplus.com/reference/functional/greater_equal/

О ссылке встроенного оператора.

Вы можете ссылаться на существующий оператор < для любого класса (конечно, если они не являются частными, защищенными или ваш класс/функция не является другом). Но оператор < для встроенных типов (bool, short, int, double) это невозможно. Событие, если вы не смотрите на стандарт С++, который вы можете увидеть из моего текста выше.