argument-dependent-lookup

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

こ雲淡風輕ζ 提交于 2019-12-30 08:24:24
问题 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

Function names in global namepsace scope cannot be found

你。 提交于 2019-12-24 06:43:54
问题 According to unqualified lookup in cppreference.com: For a name used in the definition of a function, either in its body or as part of default argument, where the function is a member of user-declared or global namespace, the block in which the name is used is searched before the use of the name, then the enclosing block is searched before the start of that block, etc, until reaching the block that is the function body. Then the namespace in which the function is declared is searched until

Does Argument-Dependent Lookup go before normal scope lookup?

牧云@^-^@ 提交于 2019-12-23 17:33:53
问题 This is the code in question that appears in §13.3 of "C++ Primer", 5ed: void swap(Foo &lhs, Foo &rhs) { using std::swap; swap(lhs.h, rhs.h); // uses the HasPtr version of swap // swap other members of type Foo } The book mentions the phenomenon of the class-specific swap not being hidden by the using declaration, and refers reader to §18.2.3: I read that section and realized that this may be related to Argument-Dependent Lookup (ADL). The following is the excerption: But I still have some

ADL does not work in constexpr functions (clang only)

我与影子孤独终老i 提交于 2019-12-23 09:20:03
问题 The following code compiles with MSVC and gcc, but not with clang. Why is that so? It seems like if ADL would not work if CallFoo () is constexpr . See the comment. template <class T> constexpr void CallFoo () // Remove constexpr to fix clang compilation error. { Foo (T ()); } class Apple {}; int main () { CallFoo<Apple> (); } constexpr void Foo (Apple) { } Clang error message (see on godbolt.org): <source>:4:5: error: use of undeclared identifier 'Foo' Foo (T ()); ^ <source>:13:5: note: in

Lambdas, local types, and global namespace

不羁岁月 提交于 2019-12-23 08:54:04
问题 This minimal program template <typename X> void foo (X x) { bar (x); } template <typename X> void bar (X x) { } int main () { foo ([]{}); } compiles with gcc (4.8.5 and 5.3) and fails to compile with clang (3.7) My analysis is as follows. bar is used in foo and declared after foo , so it is not visible at foo definition point. The only way bar can be found at foo instantiation point is via argument-dependent lookup. The only argument to both foo and bar is a lambda defined in main .

why move swap_impl in boost::swap to a separate namespace?

吃可爱长大的小学妹 提交于 2019-12-22 13:53:02
问题 I am looking into boost::swap implementation: namespace boost_swap_impl { template<class T> BOOST_GPU_ENABLED void swap_impl(T& left, T& right) { using namespace std;//use std::swap if argument dependent lookup fails swap(left,right); } template<class T, std::size_t N> BOOST_GPU_ENABLED void swap_impl(T (& left)[N], T (& right)[N]) { for (std::size_t i = 0; i < N; ++i) { ::boost_swap_impl::swap_impl(left[i], right[i]); } } } namespace boost { template<class T1, class T2> BOOST_GPU_ENABLED

why move swap_impl in boost::swap to a separate namespace?

感情迁移 提交于 2019-12-22 13:52:12
问题 I am looking into boost::swap implementation: namespace boost_swap_impl { template<class T> BOOST_GPU_ENABLED void swap_impl(T& left, T& right) { using namespace std;//use std::swap if argument dependent lookup fails swap(left,right); } template<class T, std::size_t N> BOOST_GPU_ENABLED void swap_impl(T (& left)[N], T (& right)[N]) { for (std::size_t i = 0; i < N; ++i) { ::boost_swap_impl::swap_impl(left[i], right[i]); } } } namespace boost { template<class T1, class T2> BOOST_GPU_ENABLED

Are there different rules regarding ADL or naming clashes with regard to overloaded operators?

巧了我就是萌 提交于 2019-12-22 09:58:04
问题 I think this example best illustrates my question: namespace N { class C { public: friend bool operator==(const C& c, const C& x) { return true; } friend bool f(const C& c, const C& x) { return true; } }; class D { public: bool operator==(const D& x) { bool a = C{} == C{}; // this works return true; } bool f(const D& x) { bool a = f(C{}, C{}); // this does not work return true; } }; } I have always viewed overloaded operators as being just like function except for the 'calling syntax' if you

3.4.2 Argument-dependent name lookup from n3290 Draft

霸气de小男生 提交于 2019-12-22 04:08:49
问题 A point from ISO draft n3290 section 3.4.2 paragraph 1: When the postfix-expression in a function call is an unqualified-id , other namespaces not considered during the usual unqualified lookup may be searched, and in those namespaces, namespace-scope friend function declarations not otherwise visible may be found. These modifications to the search depend on the types of the arguments (and for template template arguments, the namespace of the template argument). Here they said aboout "these

Doesn't ADL looks up static member functions?

a 夏天 提交于 2019-12-21 11:21:33
问题 This is follow up question from Does argument dependent lookup only search namespaces or classes too? , In which @David Rodríguez said "ADL will look in the enclosing namespace of the type, and also inside the type itself" . I may have got him wrong what he tried to say but I was trying this example: struct foo{ static void bar(foo* z){} }; int main(){ foo* z; bar(z); } It doesn't compiles, producing the error " ‘bar’ was not declared in this scope " . Is it the case that ADL doesn't