argument-dependent-lookup

Is there a legal way to print tuples and pairs using operator<<?

*爱你&永不变心* 提交于 2019-12-03 13:28:10
I have a set of templates/functions that allow me to print a tuple/pair assuming that each type in the tuple/pair has operator<< defined for it. Unfortunately, due to 17.4.3.1, it is illegal to add my operator<< overloads to std . Is there another way to get ADL to find my operator<< ? If not, is there any actual harm in wrapping my overload in namespace std{} ? The code for anyone interested: (I'm using gcc-4.5) namespace tuples { using ::std::tuple; using ::std::make_tuple; using ::std::get; namespace detail { template< typename...args > size_t size( tuple<args...> const& ) { return sizeof..

Why is this call to swap() ambiguous?

被刻印的时光 ゝ 提交于 2019-12-03 10:39:37
The following program #include <algorithm> #include <utility> #include <memory> namespace my_namespace { template<class T> void swap(T& a, T& b) { T tmp = std::move(a); a = std::move(b); b = std::move(tmp); } template<class T, class Alloc = std::allocator<T>> class foo {}; } int main() { my_namespace::foo<int> *a, *b; using my_namespace::swap; swap(a,b); return 0; } causes both g++ and clang to issue the following compiler error on my system: $ clang -std=c++11 swap_repro.cpp -I. swap_repro.cpp:28:3: error: call to 'swap' is ambiguous swap(a,b); ^~~~ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/

How does “using std::swap” enable ADL?

倾然丶 夕夏残阳落幕 提交于 2019-12-03 10:35:48
In What is the copy-and-swap idiom this example is shown: friend void swap(dumb_array& first, dumb_array& second) // nothrow { // enable ADL (not necessary in our case, but good practice) using std::swap; // by swapping the members of two classes, // the two classes are effectively swapped swap(first.mSize, second.mSize); swap(first.mArray, second.mArray); } How exactly does using std::swap enable ADL? ADL only requires an unqualified name. The only benefits I see for using std::swap is that since std::swap is a function template you can use a template argument list in the call ( swap<int, int

Functions with class arguments are leaked from a namespace?

跟風遠走 提交于 2019-12-03 07:43:46
问题 I have a small piece of code here for your consideration which puzzles me quite a lot. The strange thing is that it compiles on both Sun Studio and GCC even though I think it should not. Consider this: namespace name { class C { int a; }; void f(C c); void g(int a); } int main(int argc, char** argv) { name::C c; name::f(c); f(c); // <--- this compiles, strangely enough name::g(42); // g(42); <--- this does not, as I expected } The class argument from the same namespace causes the function f

Why does endl(std::cout) compile

安稳与你 提交于 2019-12-03 06:51:41
问题 Surprisingly the below code compiles and runs without error on a variety of compilers and versions. #include <iostream> int main() { endl(std::cout); return 0; } Ideone link How does it compile? I am sure there is no endl in global scope because a code like std::cout << endl; would fail unless using is used or else you need std::endl . 回答1: This behavior is called argument dependent lookup or Koenig lookup. This algorithm tells the compiler to not just look at local scope, but also the

Is it possible to take the address of an ADL function?

六月ゝ 毕业季﹏ 提交于 2019-12-03 05:30:46
Is it possible to take the address of a function that would be found through ADL? For example: template<class T> void (*get_swap())(T &, T &) { return & _________; // how do I take the address of T's swap() function? } int main() { typedef some_type T; get_swap<T>(); } Cassio Neri Honestly, I don't know but I tend towards saying that this is not possible. Depending on what you want to achieve I can suggest a workaround. More precisely, if you just need the address of a function that has the same semantics as swap called through ADL then you can use this: template <typename T> void (*get_swap()

Lookup of dependent names in C++ template instantiation

こ雲淡風輕ζ 提交于 2019-12-03 04:50:57
When I try to compile this code // void foobar(int); template <class T> struct Foo { void bar(T t) { foobar(t); }; }; void foobar(int); template class Foo<int>; with g++ 4.8.2 I get the following error message foo.cc: In instantiation of ‘void Foo<T>::bar(T) [with T = int]’: foo.cc:10:16: required from here foo.cc:5:27: error: ‘foobar’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] void bar(T t) { foobar(t); }; ^ foo.cc:8:6: note: ‘void foobar(int)’ declared here, later in the translation unit void foobar

Why Argument Dependent Lookup doesn't work with function template dynamic_pointer_cast

时间秒杀一切 提交于 2019-12-03 04:27:01
Consider the following C++ program: #include <memory> struct A {}; struct B : A {}; int main() { auto x = std::make_shared<A>(); if (auto p = dynamic_pointer_cast<B>(x)); } When compiling with MSVC 2010, I obtain the following error: error C2065: 'dynamic_pointer_cast' : undeclared identifier The error persists if auto is replaced by std::shared_ptr<A> . When I fully qualify the call with std::dynamic_pointer_cast , the program successfully compiles. Also, gcc 4.5.1 doesn't like it either: error: 'dynamic_pointer_cast' was not declared in this scope I thought that std::dynamic_pointer_cast

Why does endl(std::cout) compile

旧街凉风 提交于 2019-12-02 20:41:50
Surprisingly the below code compiles and runs without error on a variety of compilers and versions. #include <iostream> int main() { endl(std::cout); return 0; } Ideone link How does it compile? I am sure there is no endl in global scope because a code like std::cout << endl; would fail unless using is used or else you need std::endl . Gyapti Jain This behavior is called argument dependent lookup or Koenig lookup. This algorithm tells the compiler to not just look at local scope, but also the namespaces that contain the argument's type while looking for unqualified function call. For ex:

Functions with class arguments are leaked from a namespace?

醉酒当歌 提交于 2019-12-02 20:28:12
I have a small piece of code here for your consideration which puzzles me quite a lot. The strange thing is that it compiles on both Sun Studio and GCC even though I think it should not. Consider this: namespace name { class C { int a; }; void f(C c); void g(int a); } int main(int argc, char** argv) { name::C c; name::f(c); f(c); // <--- this compiles, strangely enough name::g(42); // g(42); <--- this does not, as I expected } The class argument from the same namespace causes the function f to 'leak' out of the namespace and be accessible without name:: . Does anybody have an explanation for