argument-dependent-lookup

When is ADL applied?

喜夏-厌秋 提交于 2019-12-01 23:33:57
问题 There are 3 examples: I. typedef int foo; namespace B { struct S { operator int(){ return 24; } }; int foo(B::S s){ return 0; } } int main() { int t=foo(B::S()); //24, ADL does not apply } II. namespace B { struct S { operator int(){ return 24; } }; int foo(B::S s){ return 0; } } int main() { int t=foo(B::S()); //0, ADL applies } III. namespace B { struct S { operator int(){ return 24; } }; int foo(B::S s){ return 0; } } int foo(B::S s){ return 12; } int main() { int t=foo(B::S()); //error:

When is ADL applied?

拥有回忆 提交于 2019-12-01 21:05:09
There are 3 examples: I. typedef int foo; namespace B { struct S { operator int(){ return 24; } }; int foo(B::S s){ return 0; } } int main() { int t=foo(B::S()); //24, ADL does not apply } II. namespace B { struct S { operator int(){ return 24; } }; int foo(B::S s){ return 0; } } int main() { int t=foo(B::S()); //0, ADL applies } III. namespace B { struct S { operator int(){ return 24; } }; int foo(B::S s){ return 0; } } int foo(B::S s){ return 12; } int main() { int t=foo(B::S()); //error: call of overloaded ‘foo(B::S)’ is ambiguous //ADL applies } It is not clear for me what is the actual

Range-based for loops and ADL

蹲街弑〆低调 提交于 2019-12-01 17:15:08
问题 The C++0x standard working draft states (section 6.5.4) the following about the begin() and end() calls that are implicit in a range-based for loop: 'begin' and 'end' are looked up with argument-dependent lookup (3.4.2). For the purposes of this name lookup, namespace std is an associated namespace. The way I read this, this means that the overload resolution set for the calls to begin() and end() includes all of the following: all overloads of begin() and end() that are in scope at the

Range-based for loops and ADL

时光总嘲笑我的痴心妄想 提交于 2019-12-01 17:06:07
The C++0x standard working draft states (section 6.5.4) the following about the begin() and end() calls that are implicit in a range-based for loop: 'begin' and 'end' are looked up with argument-dependent lookup (3.4.2). For the purposes of this name lookup, namespace std is an associated namespace. The way I read this, this means that the overload resolution set for the calls to begin() and end() includes all of the following: all overloads of begin() and end() that are in scope at the location where the range-based for loop is used (in particular, all overloads in the global namespace will

Why is ADL not working with Boost.Range?

一笑奈何 提交于 2019-12-01 16:14:47
Considering: #include <cassert> #include <boost/range/irange.hpp> #include <boost/range/algorithm.hpp> int main() { auto range = boost::irange(1, 4); assert(boost::find(range, 4) == end(range)); } Live Clang demo Live GCC demo this gives: main.cpp:8:37: error: use of undeclared identifier 'end' Considering that if you write using boost::end; it works just fine , which implies that boost::end is visible: Why is ADL not working and finding boost::end in the expression end(range) ? And if it's intentional, what's the rationale behind it? To be clear, the expected result would be similar to what

Cxx-prettyprint (for standard containers) defines its output operators inside namespace std - is this a standard violation?

为君一笑 提交于 2019-12-01 08:19:28
问题 I have been successfully using cxx-prettyprint: A C++ Container Pretty-Printer to log container values. (See also Pretty-print C++ STL containers) It's working like a charm on our VS-2005 (VC8) compiler. (with the prettyprint98.hpp header) While studying its interoperability with Boost.Format, I found to my surprise that it simply works out of the box, when other questions suggest it shouldn't because ADL should fail for a user provided output operator. Looking into the cxx-pp header I found

how do I call an inline friend function with the same name as a member function?

喜夏-厌秋 提交于 2019-12-01 07:13:47
问题 As described here C++11 style SFINAE and function visibility on template instantiation class member functions overshadow free functions. Using a fully qualified name usually works, however I am having a hard time with friend functions of other classes which are declared in-line. Consider the following example: namespace N { struct C { friend int f(const C& c) { return 1; } friend int g(const C& c) { return 2; } }; struct D { void f() { g(C{}); // ADL finds this ::N::f(C{}); // not found

Why doesn't a using directive affect ADL?

泪湿孤枕 提交于 2019-12-01 04:18:09
问题 I am trying to understand why the following code does not compile: namespace ns { struct S {}; } namespace alleq { inline bool operator==(const ns::S &, const ns::S &) { return true; } } namespace ns { using namespace alleq; // using alleq::operator==; // Works if you uncomment this } ns::S a; void f() { ::ns::operator==(a, a); // OK a == a; // Error: no match for 'operator==' } The first line of function f does compile, which makes me believe that namespace ns contains a function operator==

Is it possible to create a trait to answer if a type comes from std?

一个人想着一个人 提交于 2019-12-01 04:14:25
After this question by utilizing ADL one can create a trait to answer if the passed type comes from our namespace: #include <utility> namespace helper { template <typename T, typename = void> struct is_member_of_sample : std::false_type { }; template <typename T> struct is_member_of_sample< T, decltype(adl_is_member_of_sample(std::declval<T>()))> : std::true_type { }; } namespace sample { template <typename T> auto adl_is_member_of_sample(T && ) -> void; } // -- Test it namespace sample { struct X; } struct Y; static_assert(helper::is_member_of_sample<sample::X>::value, ""); static_assert(not

Can refactoring an overloaded operator into a non-member function break any code?

北慕城南 提交于 2019-12-01 03:58:34
Consider a legacy class template with overloaded addition operators += and + template<class T> class X { public: X() = default; /* implicict */ X(T v): val(v) {} X<T>& operator+=(X<T> const& rhs) { val += rhs.val; return *this; } X<T> operator+ (X<T> const& rhs) const { return X<T>(*this) += rhs; } private: T val; }; Upon code review, it is observed that + is implementable in terms of += , so why not make it a non-member (and have guaranteed symmetry for left and right arguments)? template<class T> class X { public: X() = default; /* implicit */ X(T v): val(v) {} X<T>& operator+=(X<T> const&