Оператор перегрузки% для плавающих типов - PullRequest
3 голосов
/ 09 февраля 2012

Я пытаюсь перегрузить оператор%, потому что вы не можете использовать модуль для двойных типов,

float a = 5.0; 
float b = 5.0;
a  = a % b;
// not allowed

Я пытался перегрузить оператор% с помощью такой функции:

template <>
MyClass*                MyClass<float>::operator%(Myclass &other)

Для других операций, не связанных с плавающей точкой, я использую:

template <class T>
MyClass*                MyClass<T>::operator%(MyClass &other)

Он никогда не компилировался на самом деле, я застрял и не могу найти способ обойти эту проблему, G ++ все еще предупреждает меня, что вы не можете выполнять по модулю на поплавках, что-то не так с моим синтаксисом шаблона или это действительно невозможно.

1 Ответ

6 голосов
/ 09 февраля 2012

Вы не можете перегружать операторы для примитивных типов так, как вы хотите, чтобы они работали.

Для C ++ 11 черновик n3290, §13.5 Операторские перегрузки , точка 6:

Операторная функция должна быть нестатической функцией-членом или не-функцией-членом и иметь по крайней мере один параметр, тип которого является классом, ссылкой на класс, перечислением илиссылка на перечисление.[...]

Примитивные типы не являются классами (или перечислениями), поэтому они не могут иметь функции-члены.И вы не можете создать глобальный float operator%(float&,float&), поскольку он не включает класс или перечисление в списке параметров.(См. Также C ++ FAQ 26.10 «Можно ли определить перегрузку оператора, которая работает со встроенными / внутренними / примитивными типами?» .)
Вам нужен хотя бы один из терминов в % выражение, чтобы быть пользовательским типом.

Вы можете создать класс Float и определить любые операции, которые вы хотите над ним, но вы не можете заставить a = a % b; использовать вашу функцию, если оба aи b - это float с.

Или вы можете #include <cmath> и использовать std::fmod:

#include <iostream>
#include <cmath>

int main()
{
    float a = 13.0f;
    float b = 5.0f;
    a  = std::fmod(a, b);
    std::cout << a << std::endl;
    return 0;
}

Простой пример с пользовательской "оболочкой-поплавком" (неполный, вероятно,не совсем безопасно, как есть, но может помочь вам начать):

#include <iostream>
#include <cmath>

class Float {
    private:
        float val;
    public:
        Float(float f): val(f) {};

        Float operator%(Float const& other) const {
            return std::fmod(val, other.val);
        }
        Float operator%(float const& other) const {
            return std::fmod(val, other);
        }
        // conversion operator could be handy
        operator float() { return val; }
};

int main()
{
    Float a = 13.0f;
    Float b = 5.0f;
    Float c  = a % b;
    std::cout << c << std::endl;
    // this also works
    Float d = 13.0f;
    float e = 5.0f;
    float f  = d % e;
    std::cout << f << std::endl;
    return 0;
}
...