gpt4 book ai didi

c++ - 从属名称解析和命名空间标准/标准库

转载 作者:太空狗 更新时间:2023-10-29 23:11:01 24 4
gpt4 key购买 nike

在回答 this SO question 时(最好阅读 this "duplicate"),我想出了以下解决方案来解决运算符的相关名称解析问题:

[temp.dep.res]/1:

In resolving dependent names, names from the following sources are considered:

  • Declarations that are visible at the point of definition of the template.
  • Declarations from namespaces associated with the types of the function arguments both from the instantiation context (14.6.4.1) and from the definition context.
#include <iostream>
#include <utility>

// this operator should be called from inside `istream_iterator`
std::istream& operator>>(std::istream& s, std::pair<int,int>& p)
{
s >> p.first >> p.second;
return s;
}

// include definition of `istream_iterator` only after declaring the operator
// -> temp.dep.res/1 bullet 1 applies??
#include <iterator>

#include <map>
#include <fstream>

int main()
{
std::ifstream in("file.in");

std::map<int, int> pp;
pp.insert( std::istream_iterator<std::pair<int, int>>{in},
std::istream_iterator<std::pair<int, int>>{} );
}

但是 clang++ 3.2 和 g++ 4.8 找不到这个运算符(名称解析)。

不包含 <iterator>定义“模板定义点” istream_iterator ?

编辑:作为 Andy Prowl指出,这与标准库无关,而是与名称查找有关(可以通过使用多个 operator>> 模拟标准库来证明,至少一个在假 istream 的命名空间中)。


Edit2:解决方法,使用 [basic.lookup.argdep]/2 bullet 2

#include <iostream>
#include <utility>

// can include <iterator> already here,
// as the definition of a class template member function
// is only instantiated when the function is called (or explicit instantiation)
// (make sure there are no relevant instantiations before the definition
// of the operator>> below)
#include <iterator>

struct my_int
{
int m;
my_int() : m() {}
my_int(int p) : m(p) {}
operator int() const { return m; }
};

// this operator should be called from inside `istream_iterator`
std::istream& operator>>(std::istream& s, std::pair<my_int,my_int>& p)
{
s >> p.first.m >> p.second.m;
return s;
}

#include <map>
#include <fstream>

int main()
{
std::ifstream in("file.in");

std::map<int, int> pp;
pp.insert( std::istream_iterator<std::pair<my_int, my_int>>{in},
std::istream_iterator<std::pair<my_int, my_int>>{} );
}

当然你也可以用自己的pair类型,只要解决方法在自定义的命名空间中引入关联类 operator>> .

最佳答案

这里的问题是你调用 operator >> 的点正在制作的是 std 内的某处命名空间,参数类型所在的命名空间是 std .

假设编译器可以找到 operator >>在发生调用的命名空间或参数类型所在的命名空间(在本例中均为 std 命名空间),无论重载解析是否可行(之后执行 名称查找),它不会费心寻找 operator >> 的更多重载在父 namespace 中。

不幸的是,您的 operator >>存在于全局命名空间中,因此找不到。

关于c++ - 从属名称解析和命名空间标准/标准库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52556944/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com