argument-dependent-lookup

ADL with typedefs from another namespace

蹲街弑〆低调 提交于 2019-11-29 05:48:22
I have something like this: #include <iostream> namespace N { typedef std::pair<int, double> MyPair; std::ostream& operator << (std::ostream& o, MyPair const & mypair) { /// } } int main() { N::MyPair pr; std::cout << pr; } This naturally doesn't work, because ADL won't find operator<< because namespace N is not associated with MyPair (unfortunately). Afaik one may not add to namespace std, so if I chose to define operator << in std that would be kinda illegal. So... what to do in such situations? I don't want to explicitly qualify operator << , nor do I wish to write using namespace N . So,

Where should I define operator >> for my specialization of std::pair?

拜拜、爱过 提交于 2019-11-29 03:27:52
Consider the following program: #include <iostream> #include <iterator> #include <vector> #include <utility> using namespace std; //just for convenience, illustration only typedef pair<int, int> point; //this is my specialization of pair. I call it point istream& operator >> (istream & in, point & p) { return in >> p.first >> p.second; } int main() { vector<point> v((istream_iterator<point>(cin)), istream_iterator<point>()); // ^^^ ^^^ //extra parentheses lest this should be mistaken for a function declaration } This fails to compile because as soon as ADL finds operator >> in namespace std it

Is ADL the only way to call a friend inline function?

江枫思渺然 提交于 2019-11-28 22:56:22
Let us define f , as a friend function of S , inside the declaration of S : struct S { friend void f() {} }; I cannot find a way to call f . Is it true, then, that such an inline friend function can only be called with argument-dependant lookup ? struct S { friend void f() {} friend void g(S const&) {} } const s; int main() { // f(); // error: 'f' was not declared in this scope // S::f(); // error: 'f' is not a member of 'S' g(s); // S::g(s); // error: 'g' is not a member of 'S' } Bonus: what if I want to get a function-pointer/ std::function /lambda to g ? Is it true, then, that such an

C++11 style SFINAE and function visibility on template instantiation

拜拜、爱过 提交于 2019-11-28 09:52:57
问题 I'm not sure if this has anything to do with sfinae, or just something thats relevant for any templated function. I am attempting to use sfinae to enable/disable a member function based on existence of corresponding free function, which in turn is enabled/disabled based on existance of member function in another type, all using method described here: struct S; template <typename T> inline auto f(S& s, T const& t) -> decltype(t.f(s), void()) { t.f(s); } struct S { template <typename T> auto f

Should custom containers have free begin/end functions?

浪子不回头ぞ 提交于 2019-11-28 04:17:16
When creating a custom container class that plays by the usual rules (i.e. works with STL algorithms, works with well-behaved generic code, etc.), in C++03 it was sufficient to implement iterator support and member begin/end functions. C++11 introduces two new concepts - range-based for loop and std::begin/end. Range-based for loop understands member begin/end functions, so any C++03 containers support range-based for out of the box. For algorithms the recommended way (according to 'Writing modern C++ code' by Herb Sutter) is to use std::begin instead of member function. However, at this point

Range-based for statement definition redundancy

為{幸葍}努か 提交于 2019-11-28 00:41:47
Looking at n3092, in §6.5.4 we find the equivalency for a range-based for loop. It then goes on to say what __begin and __end are equal to. It differentiates between arrays and other types, and I find this redundant (aka confusing). It says for arrays types that __begin and __end are what you expect: a pointer to the first and a pointer to one-past the end. Then for other types, __begin and __end are equal to begin(__range) and end(__range) , with ADL. Namespace std is associated, in order to find the std::begin and std::end defined in <iterator> , §24.6.5. However, if we look at the

How do I write an ADL-enabled trailing return type, or noexcept specification?

自闭症网瘾萝莉.ら 提交于 2019-11-27 17:58:22
Imagine I'm writing some container template or something. And the time comes to specialize std::swap for it. As a good citizen, I'll enable ADL by doing something like this: template <typename T> void swap(my_template<T>& x, my_template<T>& y) { using std::swap; swap(x.something_that_is_a_T, y.something_that_is_a_T); } This is very neat and all. Until I want to add an exception specification. My swap is noexcept as long as the swap for T is noexcept . So, I'd be writing something like: template <typename T> void swap(my_template<T>& x, my_template<T>& y) noexcept(noexcept(swap(std::declval<T>(

Should custom containers have free begin/end functions?

只谈情不闲聊 提交于 2019-11-27 00:19:41
问题 When creating a custom container class that plays by the usual rules (i.e. works with STL algorithms, works with well-behaved generic code, etc.), in C++03 it was sufficient to implement iterator support and member begin/end functions. C++11 introduces two new concepts - range-based for loop and std::begin/end. Range-based for loop understands member begin/end functions, so any C++03 containers support range-based for out of the box. For algorithms the recommended way (according to 'Writing

How do I write an ADL-enabled trailing return type, or noexcept specification?

久未见 提交于 2019-11-26 22:37:10
问题 Imagine I'm writing some container template or something. And the time comes to specialize std::swap for it. As a good citizen, I'll enable ADL by doing something like this: template <typename T> void swap(my_template<T>& x, my_template<T>& y) { using std::swap; swap(x.something_that_is_a_T, y.something_that_is_a_T); } This is very neat and all. Until I want to add an exception specification. My swap is noexcept as long as the swap for T is noexcept . So, I'd be writing something like:

Range-based for statement definition redundancy

眉间皱痕 提交于 2019-11-26 21:48:28
问题 Looking at n3092, in §6.5.4 we find the equivalency for a range-based for loop. It then goes on to say what __begin and __end are equal to. It differentiates between arrays and other types, and I find this redundant (aka confusing). It says for arrays types that __begin and __end are what you expect: a pointer to the first and a pointer to one-past the end. Then for other types, __begin and __end are equal to begin(__range) and end(__range) , with ADL. Namespace std is associated, in order to