C++: как использовать один и тот же тип данных с двумя разными именами в двух разных перегруженных функциях?


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

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

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

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

6 2

6 ответов:

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

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

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

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

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

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

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

Как упоминалось в других ответах, это не работает, потому что 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.
    }
    

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

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

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