2017-04-06 37 views
5

下面的代码编译失败ADL使用std类型无法找到经营者

namespace A { 
using C = std::vector<std::string>; 
std::ostream& operator << (std::ostream& lhs, const C& rhs) { 
    lhs << 5; 
    return lhs; 
} 
} 
int main() 
{ 
    A::C f; 
    std::cout << f; 
    return 0; 
} 

与错误

Error C2679 binary '<<': no operator found which takes a right-hand operand of type 'A::C' (or there is no acceptable conversion) 

显然它不能找到< <运营商大概是由于考虑到c是一个类来自std命名空间。有什么方法可以确保编译器找到这个操作符或者解决这个问题吗?

+0

以运营商出的命名空间应该工作的。 – interjay

+0

'A :: operator <<(std :: cout,f);'但是我怀疑你在找什么。 – DeiDei

+4

'A :: C'不是一个类型定义,它只是一个别名。该类型存在于'std'命名空间中。 –

回答

2

A::C只是一个类型别名,别名是透明的。他们不“记住”他们来自哪里。当我们进行依赖于参数的查找并确定相关的命名空间是什么时,我们只考虑类型的关联命名空间 - 而不是让我们在那里的别名。您不能只将关联的名称空间添加到现有类型。 f(其类型为std::vector<std::string>)的特定关联名称空间为std,该关联名称空间没有与其关联的operator<<。由于没有使用普通查找找到的operator<<,也没有使用ADL发现的,所以调用失败。

现在,我说你不能只添加关联的名称空间到现有的类型。但是,你当然可以只创建新类型:

namespace A { 
    struct C : std::vector<std::string> { }; 
} 

或:

namespace A { 
    // template parameters are also considered for associated namespaces 
    struct S : std::string { }; 
    using C = std::vector<S>; 
}