【发布时间】:2014-06-02 23:53:30
【问题描述】:
我遇到了这个问题:
// A.h
#include <vector>
typedef std::vector<unsigned char> Buffer;
Buffer &operator+=(Buffer &a, Buffer const &b);
// B.h
namespace Bar
{
struct Qux { };
Qux &operator+=(Qux &a, Qux const &b);
}
// Foo.cpp
#include "A.h"
#include "B.h" // comment this out, error goes away
namespace Bar
{
void foo()
{
Buffer a, b;
a += b; // error
}
}
问题(如here 所述)是a += b; 无法编译,因为Bar::operator+=(Qux&, Qux const &) 隐藏了::operator+=;而 ADL 没有找到 ::operator+,因为在这种情况下 ADL 只搜索 namespace std;。
这很棘手,因为只有在包含 B.h 时才会出现问题——但 B.h 显然与 Buffer 无关。代码不应该根据我是否包含另一个标题而中断。
(其实我是在换编译器的时候才发现的,之前我用的编译器确实名字查找不正确,接受了代码)。
我的问题是:A.h 中的过载是否因为这个问题而成为一个坏主意?
我现在通过在namespace Bar 中使用B.h 来解决这个问题,但这似乎很老套,有更好的选择吗?
【问题讨论】:
-
如果在代码中添加
using ::operator+=;会怎样? -
我认为Kerrek 的意思是如果你将
using ::operator+=;添加到foo会发生什么? -
你的意思是把它添加到每个使用它的函数中?似乎比在
B.h中做一次更 hacker :) -
如果您要为
std命名空间中定义的任何类型重载任何运算符,我建议在std命名空间中执行此操作。这与 ADL 配合得很好。 -
@RSahu 很遗憾,它是添加到
std的 UB(参见[namespace.std]#1)
标签: c++ operator-overloading argument-dependent-lookup