Сделать преобразование в нативный тип явным в C ++ - PullRequest
4 голосов
/ 27 апреля 2010

Я пытаюсь написать класс, который реализует 64-битные числа для компилятора, который не поддерживает long long, для использования в существующем коде. По сути, я должен иметь возможность использовать где-то typedef, который выбирает, хочу ли я использовать long long или мой класс, а все остальное должно компилироваться и работать.

Итак, мне, очевидно, нужны конструкторы преобразования из int, long и т. Д. И соответствующие операторы преобразования (приведения) к этим типам. Это, кажется, вызывает ошибки с арифметическими операторами. Для нативных типов компилятор «знает», что когда вызывается operator*(int, char), он должен преобразовать char в int и вызывать operator*(int, int) (вместо того, чтобы приводить, например, int к char). В моем случае это путает между различными встроенными операторами и теми, что я создал.

Мне кажется, что если бы я мог как-то пометить операторы преобразования как явные, это решило бы проблему, но, насколько я могу судить, ключевое слово explicit предназначено только для конструкторов (и я не могу создавать конструкторы). для встроенных типов).

Так есть ли способ пометить приведение как явное? Или я лаю не на том дереве и есть другой способ решить это? Или, может быть, я просто делаю что-то не так ...

EDIT:

Небольшое разъяснение о том, что я хочу сделать: у меня есть проект, который использует 64-битные ('long long') операции во многих местах, и я пытаюсь перенести его на платформу, которую не делает имеет встроенную поддержку 64-битных переменных / операций. Несмотря на то, что у меня есть источник для проекта, я действительно предпочел бы не ходить по тысячам мест, где находятся встроенные операторы и приведения в стиле C, и менять их.

Что касается самого кода, проект имеет следующие определения и виды кода:

typedef long long i64;  // I would like to only have to change this to use my class instead of "long long"

int a;
unsigned b;
int c = ((i64)a*b)>>32;

Что касается реализации класса, у меня есть следующее:

class Long64 {
public:

Long64();
Long64(const Long64&);
Long64(int);
Long64(long);
Long64(unsigned int);
Long64(unsigned long);

operator int() const;
operator long() const;
operator unsigned int() const;
operator unsigned long() const;

friend Long64 operator*(int l, const Long64& r);
friend Long64 operator*(const Long64& l, int r);
friend Long64 operator*(long l, const Long64& r);
friend Long64 operator*(const Long64& l, long r);
}

Ответы [ 2 ]

3 голосов
/ 27 апреля 2010

Чтобы избежать путаницы с компилятором, вы поможете ему, определив комбинацию вашего класса и встроенных типов для всех арифметических операторов. Например, для оператора + вам нужно определить + беззнаковые

MyClass operator+(char, MyClass const&);
MyClass operator+(MyClass const&, char);
MyClass operator+(short, MyClass const&);
MyClass operator+(MyClass const&,short);
MyClass operator+(MyClass const&,int);

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

Конечно, все эти методы будут использовать перегрузку Оператор MyClass + (MyClass const &, MyClass const &);

путем явного преобразования одного из параметров в ваш класс MyClass

MyClass operator+(char c, MyClass const& m) { return MyClass(c)+m;}

Это немного громоздко, я знаю, но это должно избежать конфликтов.

2 голосов
/ 27 апреля 2010

Вы должны создавать методы со значимыми именами вместо операторов преобразования - например, toLongLong() вместо operator long long() - так вы сможете писать код, который легко поймут как люди, так и компилятор. Это единственное разумное решение, когда у вас так много операторов преобразования, что даже компилятор не может получить то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...