以下片段: #include <memory> #include <utility> namespace foo { template <typename T> void swap(T& a, T& b) { T tmp = std::move(a); a = std::move(b); b = std::move(tmp); } struct bar { }; } void baz() { std::unique_ptr<foo::bar> ptr; ptr.reset(); } 不为我编译: $ g++ -std=c++11 -c foo.cpp In file included from /usr/include/c++/5.3.0/memory:81:0, from foo.cpp:1: /usr/include/c++/5.3.0/bits/unique_ptr.h: In […]
当创build一个自定义的容器类,按照通常的规则(即与STLalgorithm一起工作,使用行为良好的通用代码等)工作时,在C ++ 03中,实现迭代器支持和成员开始/结束函数就足够了。 C ++ 11引入了两个新的概念 – 基于范围的循环和std :: begin / end。 基于范围的for循环理解成员开始/结束函数,所以任何C ++ 03容器都支持基于范围的开箱即用。 对于algorithm推荐的方法(根据Herb Sutter编写的“现代C ++代码”)是使用std :: begin代替成员函数。 然而,在这一点上,我不得不问 – 推荐的方法来调用一个完全合格的begin()函数(即std :: begin(c))或依赖于ADL并调用begin(c)? ADL在这种情况下似乎没用 – 因为如果可能,std :: begin(c)委托给c.begin(),通常的ADL好处似乎不适用。 如果每个人都开始依赖ADL,所有的定制容器都必须在必需的名称空间中实现额外的begin()/ end()自由函数。 然而,有几个消息来源似乎暗示了不合格的开始/结束呼叫是推荐的方式(即https://svn.boost.org/trac/boost/ticket/6357 )。 那么什么是C ++ 11的方式? 容器库作者应该为他们的类编写额外的开始/结束函数,以便在不使用名称空间std的情况下支持非限定的开始/结束调用; 或使用std :: begin;?
我正在阅读关于参数相关查找 的C ++编程语言第4版 (由Bjarne Stroustrup撰写 )。 这里是引用(26.3.6,过度的ADL): 依赖于参数的查找(通常称为ADL)对于避免冗长是非常有用的(14.2.4)。 例如: #include <iostream> int main() { std::cout << "Hello, world" << endl; // OK because of ADL } 没有依赖于参数的查找, endl操纵器将不会被发现。 实际上,编译器注意到<<的第一个参数是std定义的一个ostream 。 因此,它在std查找endl并find它(在<iostream> )。 这里是编译器(C ++ 11模式)产生的结果 : prog.cpp: In function 'int main()': prog.cpp:4:36: error: 'endl' was not declared in this scope std::cout << "Hello, world" << […]
前段时间我读了一篇文章,解释了依赖于参数的查找的几个缺陷,但是我再也找不到了。 这是关于获得你不应该访问的东西或类似的东西。 所以我想在这里问:ADL的陷阱是什么?
C ++规范的哪一部分通过在关联的命名空间集合中查找函数模板来限制依赖于参数的查找? 换句话说,为什么最后的main调用不能编译? namespace ns { struct foo {}; template<int i> void frob(foo const&) {} void non_template(foo const&) {} } int main() { ns::foo f; non_template(f); // This is fine. frob<0>(f); // This is not. }