ADL using std types fails to find operator

*爱你&永不变心* 提交于 2019-12-28 22:17:06

问题


The following code fails to compile

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;
}

with the error

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

Obviously it cant find the << operator presumably due to considering C to be a class from the std namespace. Is there some way to ensure the compiler finds this operator or otherwise work around the problem?


回答1:


A::C is just a type alias, and aliases are transparent. They don't "remember" where they came from. When we do argument-dependent lookup and figure out what the associated namespaces are, we only consider the associated namespaces of the types - not the alias that got us there. You can't just add associated namespaces to existing types. The specific associated namespace of f (which is of type std::vector<std::string>) is std, which doesn't have an operator<< associated with it. Since there's no operator<< found using ordinary lookup, nor is there one found using ADL, the call fails.

Now, I said you can't just add associated namespaces to existing types. But you can of course just create new types:

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

or:

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


来源:https://stackoverflow.com/questions/43253306/adl-using-std-types-fails-to-find-operator

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!