Как я могу передать члены `int` и` unsigned int` по ссылке или по указателю в одну и ту же функцию? - PullRequest
0 голосов
/ 21 марта 2012

У меня есть функция C ++ из 20-30 строк, которая ссылалась на int для возможного обновления.Теперь я заменяю элемент, который был передан ему, элементом члена, инкапсулирующим больше данных, что-то вроде:

searchState.matchedOK = specificSearch(*pageIndices.GetStringIByRef(), searchState); //new, and overwritten.
searchState.matchedOK = specificSearch(pageOffsetInText, searchState); //old

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

Возможно ли это с простыми приведениями?

Если вам нужен код:

static bool specificSearch(int &matchLocation, const SearchSpecs &specs) {/**/}

и недавно добавленный член:

inline unsigned int *GetStringIByRef() {return &stringI;}

Ответы [ 4 ]

2 голосов
/ 21 марта 2012

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

template<typename IntType>
static bool specificSearch(IntType &matchLocation, const SearchSpecs &specs) {/**/}

Это позволит вам передать любой тип.

1 голос
/ 21 марта 2012

Вы можете сделать это с помощью шаблонов:

template<typename T>
static bool specificSearch(T& matchLocation, const SearchSpecs& specs) {/**/}

И присвоить matchLocation внутри функции. Таким образом, вы можете использовать любой тип, который можно назначить любому типу, который вы назначаете для matchLocation в функции.

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

// leaving this undefined, which will cause a linker error if you use it with other types
template<typename T>
static bool specificSearch(T& matchLocation, const SearchSpecs& specs);

template<>
static bool specificSearch<int>(int& matchLocation, const SearchSpecs& specs) {
    /* definition */
}

template<>
static bool specificSearch<unsigned int>(unsigned int& matchLocation, const SearchSpecs& specs) {
    // use the other one to avoid code duplication
    int tmp = matchLocation;
    bool retval = specificSearch(tmp, specs);
    matchLocation = tmp;
    return retval;
}

Обратите внимание, что вы, вероятно, получите предупреждения о преобразованиях между int и unsigned int с использованием этих функций, поскольку диапазоны двух типов различаются.

1 голос
/ 21 марта 2012

Ваша основная проблема в том, что ваша функция specificSearch присваивает объекту int. Но то, что вы хотите написать, это unsigned int объект. К счастью, строгие правила псевдонимов позволяют нам писать в unsigned int, как если бы это было int. Система типов не совсем поощряет это, но ее можно убедить:

searchState.matchedOK = specificSearch(*reinterpret_cast<int*>(pageIndices.GetStringIByRef()), searchState);

Этот тип полагается на записываемое значение в общем диапазоне двух типов (от 0 до INT_MAX). Я говорю «что-то вроде», потому что в системах дополнения 2 результат записи значения вне этого диапазона совпадает с результатом преобразования значения в unsigned int. В системах, не дополняющих 2, которые на практике не существуют, но в принципе мешают нашим попыткам создания переносимого кода, результат будет другим и, следовательно, вероятно неправильным.

Было бы лучше, если возможно, определить перегрузку specificSearch:

static bool specificSearch(unsigned int &matchLocation, const SearchSpecs &specs) {
    int loc;
    bool retval = specificSearch(loc, specs);
    if (retval) { // I'm guessing here about the meaning of the return value
        matchLocation = loc; // converts int to unsigned int
    }
    return retval;
}

Предполагается, что функция-обертка может определить, является ли "реальный" specificSearch назначенным loc или нет, так что она знает, назначать или нет matchLocation. Если вызывающая функция не может каким-то образом выяснить это, это не сработает (и если specificSearch разрешено назначать, а затем выдавать исключение, вам также необходимо учитывать это).

Было бы разумнее, если возможно, изменить stringI на правильный тип.

0 голосов
/ 21 марта 2012

Я вижу несколько вопросов здесь. Прежде всего, в зависимости от ваших намерений может быть лучше вернуть просто stringI по значению. В противном случае вы можете настроить его подпись следующим образом:

inline unsigned int &GetStringIByRef() { return stringI; }

для использования ссылок на C ++.

Что касается

static bool specificSearch(int &matchLocation, const SearchSpecs &specs) {/**/}

вы бы назвали это затем следующим образом:

searchState.matchedOK = specificSearch(reinterpret_cast<unsigned int&>(pageIndices.GetStringIByRef()), searchState);

По-прежнему зависит от самого объекта (в случае, если это const), я считаю.

Если что-то неясно или я пропустил суть, прокомментируйте, и я исправлю свой ответ.

...