使用std类型的ADL无法找到运算符

时间:2017-04-06 11:04:11

标签: c++ c++14

以下代码无法编译

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)   

显然它无法找到&lt;&lt;运算符可能是因为将C视为std命名空间中的一个类。有没有办法确保编译器找到此运算符或解决问题?

1 个答案:

答案 0 :(得分:5)

A::C只是一个类型别名,别名是透明的。他们不记得&#34;他们来自哪里。当我们进行依赖于参数的查找并找出相关命名空间的内容时,我们只考虑类型的关联命名空间 - 而不是那些让我们在那里的别名。您不能仅将关联的命名空间添加到现有类型。 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>;
}