C ++: Как использовать один и тот же тип данных с двумя разными именами в двух разных перегруженных функциях? - PullRequest
2 голосов
/ 24 ноября 2010

У меня есть следующее объявление, чтобы понять, что в моем коде используются разные операции:

typedef unsigned int SOMEIDTYPE;

Теперь, когда я создаю две перегруженные функции:

string something(const unsigned int &val){ ... itoa(val) ... }
string something(const SOMEIDTYPE &val){ ... IDTABLE[val] ... }

Я получаю ошибку: error C2084: function 'std::string something(const unsigned int &)' already has a body

Итак, как я могу перегрузить эту функцию, чтобы использовать эти два разных типа данных по-разному и выполнять различные операции, как показано выше?

Редактировать: Причина перегрузкиявляется то, что я вызываю эту функцию внутри функции шаблона.

Ответы [ 6 ]

4 голосов
/ 24 ноября 2010

Используйте сильный typedef. У Boost есть один. Стандартный typedef недостаточен для этого требования.

4 голосов
/ 24 ноября 2010

Это не отдельные типы данных, typedef не создает отдельный тип, он создает псевдоним. Следовательно, для компилятора он видит две функции с одним и тем же именем, которые принимают один аргумент, оба одинакового типа.

2 голосов
/ 24 ноября 2010

A typedef создает только псевдоним, но не создает новый тип.

Если вы действительно хотите сделать что-то подобное, вам нужно создать новый тип. Вы можете создать класс для этой цели, но для того, чтобы этот класс вел себя как int, вам необходимо выполнить некоторую работу:

class SOMEIDTYPE
{
public:
  SOMEIDTYPE();
  SOMEIDTYPE(const int&);
  SOMEIDTYPE& operator=(const SOMEIDTYPE&);
  operator int() const;
private:
  int val_;
};

Теперь вы можете перегрузить на SOMEIDTYPE

1 голос
/ 24 ноября 2010

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

Существует два способа обойти это:

  1. Дайте перегрузкам разные имена:

    string somethingInt(...)...
    string somethingID(...)...
    
  2. Создайте новый класс / структуру с новым именем.Чтобы оно работало как целое число, вы можете перегрузить различные операторы.

    struct SOMEIDTYPE {
        private: int _val;
        public:
        SOMEIDTYPE & operator=(const SOMEIDTYPE &rhs) {
            _val = rhs._val;
        }
        SOMEIDTYPE & operator=(const int &rhs) {
            _val = rhs;
        }
        //etc.
    }
    
1 голос
/ 24 ноября 2010

Вы не можете.Компилятор использует сигнатуру метода, чтобы решить, какой из них вызвать.Если методы имеют идентичные функции, компилятор не может понять это.

0 голосов
/ 24 ноября 2010

Чтобы сделать это, вам нужно обернуть второй тип в какой-нибудь класс, с макушки головы, что-то вроде:

struct SOMEIDTYPE
{
    operator unsigned int&() { return _i;};
    SOMEIDTYPE(unsigned int ui):  _i(ui) {;};
    private:
    unsigned int _i;
};

Это создает особый тип, который вы можете использовать, как вы ожидаете. (Кстати, мой C ++ немного ржавый, поэтому синтаксис может быть немного выше.)

...