使用std类型的ADL找不到运算符 [英] ADL using std types fails to find operator

查看:65
本文介绍了使用std类型的ADL找不到运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码无法编译

 命名空间A {
使用C = std :: vector< std: :string> ;;
std :: ostream&运算符<< (std :: ostream& lhs,const C& rhs){
lhs<< 5;
lhs;
}
}
int main()
{
A :: C f;
std :: cout<< F;
返回0;
}

有错误

 错误C2679二进制'<<':没有找到采用'A :: C'类型的右侧操作数的运算符(或没有可接受的转换)

显然,它找不到<<可能是因为考虑到C是std命名空间中的类。有什么方法可以确保编译器找到该运算符或以其他方式解决该问题?

解决方案

A :: C 只是类型别名,别名是透明的。他们不会记住他们的来源。当我们进行依赖于参数的查找并弄清楚关联的名称空间是什么时,我们仅考虑 types 的关联名称空间-而不是使我们到达那里的别名。您不仅可以将关联的名称空间添加到现有类型。 f (类型为 std :: vector< std :: string> )的特定关联命名空间为 std ,它没有与 operator<< 相关联。由于没有使用普通查找找到 operator< ,也没有使用ADL找到该调用,因此调用失败。



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

 命名空间A {
struct C:std :: vector< std :: string> {};
}

或:

 命名空间A {
//关联的命名空间也考虑模板参数
struct S:std :: string {};
使用C = std :: vector< S>
}


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?

解决方案

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

这篇关于使用std类型的ADL找不到运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆