Как использовать функцию + = в пространстве имен - PullRequest
2 голосов
/ 14 октября 2011

Как правильно использовать эту функцию '+ =', если функция объявлена ​​в пространстве имен?

namespace WinFile
{
     std::stack <tstring> operator += ( std::stack <tstring>& s1, std::stack <tstring> s2 )
     {
        // Post:

     if ( s1 == s2 )
     {
       return s1;
     }

        while ( !s2.empty() )
        {
           s1.push( s2.top() );
           s2.pop();
        } 

        return s1;
   }
}

Теперь, как мне использовать эту функцию ( без использования пространства имен WinFile ):

std::stack <tstring> s1;
std::stack <tstring> s2;
// ...after adding some values to the stacks
s1 += s2;                // this gets a compile error
s1 WinFile::+= s2        // this says its invalid to have a ':' infront of a +=

Ответы [ 6 ]

6 голосов
/ 14 октября 2011

Как уже предлагалось, вы можете использовать предложение "using":

using WinFile::operator+=;

или

using namespace WinFile;

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

s1 = WinFile::operator +=( s1, s2 );

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

4 голосов
/ 14 октября 2011

В функции, которая использует +=, добавьте:

using ::WinFile::operator+=;

Это сделает ваш оператор подходящим для рассмотрения.(Вы можете опустить ведущий ::, если нет двусмысленности.)

2 голосов
/ 14 октября 2011

Имя операторной функции содержит ключевое слово operator, и ваш конкретный оператор является свободной функцией, поэтому квалифицированный вызов будет:

WinFile::operator+=(s1, s2);

Я не уверен, что в любом случае это звуковой дизайн, вы (пытаетесь) расширить интерфейс std::stack, добавив функции, которые не определены в том же пространстве имен типа - это как-то против принцип интерфейса и, более того, вы добавляете операторы ... которые громоздки в использовании, если вы не вызываете их из того же пространства имен, в котором они определены (или они вводятся в область действия с помощью объявления using), или они определено в том же пространстве имен, где определен тип (поэтому ADL будет их подбирать). Вероятно, лучше избегать обоих или, по крайней мере, предоставлять реальное имя функции.

По определению самого оператора семантика странная : если оба стека эквивалентны, то вы ничего не делаете, а если они разные, вы перемещаете все содержимое второго стека в первый ... а затем также вернуть копию! Это, вероятно, вызовет сюрпризы в будущем. Если вы хотели проверить, ссылаются ли они на один и тот же объект, поскольку второй аргумент является копией, это будет невозможно (т. Е. Вызывающая сторона не может предоставить ссылку на копию)

1 голос
/ 14 октября 2011

Другая возможность - пространство имен, содержащее tstring, является связанным пространством имен для целей поиска, включающего std::stack<tstring>.Поэтому, если вы можете изменить это пространство имен, вы можете поместить свой operator+= в то же пространство имен, что и tstring.Либо определите его там, либо поставьте using ::WinFile::operator+= там.

Очевидно, что это не поможет, если tstring находится в глобальном пространстве имен.

0 голосов
/ 14 октября 2011

Используйте решение Керрека using WinFile::operator+=, но для полноты я думаю, что это можно сделать:

WinFile::operator+=(s1, s2);

Я отмечу, что я считаю, что перегрузка += означает "протолкнуть стек" вбыть в невероятно плохой форме.

0 голосов
/ 14 октября 2011

Вам нужно wirte

using namespace WinFile;

в вашем файле реализации (* .cpp)

...