如何在命名空间中使用+ =函数

时间:2011-10-14 07:22:21

标签: c++ syntax namespaces overloading

如果在命名空间中声明函数,如何才能正确使用这个'+ ='函数?

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 个答案:

答案 0 :(得分:6)

如前所述,您可以使用“using”子句:

using WinFile::operator+=;

using namespace WinFile;

或者您可以使用以下代码直接使用该功能:

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

其中没有一个是特别理想的,但据我所知,没有其他方法可以做到这一点。

答案 1 :(得分:4)

在使用+=的函数中,添加:

using ::WinFile::operator+=;

这将使您的运营商有资格考虑。 (如果没有歧义,您可以省略前导::。)

答案 2 :(得分:2)

运算符函数的名称包含关键字operator,您的特定运算符是自由函数,因此符合条件的调用将是:

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

我不确定这是一个合理的设计,你是(尝试)通过添加未在该类型的同一名称空间中定义的函数来扩展std::stack的接口 - 这是以某种方式反对接口原则,更是如此,你要添加运算符......除非你从它们被定义的相同命名空间中调用它们(或者通过using声明将它们带入范围),否则它们使用起来很麻烦或者它们是在定义类型的同一名称空间中定义的(因此ADL会选择它们)。最好避免两者或至少为函数提供真实姓名。

关于运算符本身的定义,语义是 strange :如果两个堆栈都是等价的,那么你什么也不做,而如果它们不同,你将第二个堆栈的所有内容移动到第一个堆栈一个...然后还返回一份副本!这可能会在未来引起惊喜。如果您要检查的是它们是否引用同一个对象,因为第二个参数是副本,则不可能(即调用者无法提供对副本的引用)

答案 3 :(得分:1)

另一种可能性 - 包含tstring的命名空间是一个关联的命名空间,用于涉及std::stack<tstring>的查找。因此,如果您可以修改该命名空间,则可以将operator+=放在与tstring相同的命名空间中。在那里定义它,或者将using ::WinFile::operator+=放在那里。

显然,如果tstring在全局命名空间中,那对你没有帮助。

答案 4 :(得分:0)

你需要写

using namespace WinFile;

在您的实施文件(* .cpp)

答案 5 :(得分:0)

使用Kerrek的using WinFile::operator+=解决方案,但为了完整起见,我相信可以这样做:

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

我会注意到,我认为超载+=意味着“推入堆栈”的形式非常糟糕。