ADL inhibited if the name of the function is enclosed in parenthesis??

Hi,

I found this phrase which I don't understand and it's about ADL lookup:

<comment>
ADL inhibited if the name of the function is enclosed in parenthesis
</comment>

Any explanations or examples?

I tried this code to see but Visual Studio 2017 does not care about this parenthesis:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using namespace std;

namespace N
{
	struct S
	{
		int i;
	};
	void f(S s)
	{
		cout << s.i << endl;
	}
	void g(S s)
	{
		cout << s.i << endl;
	}
	void h(int i)
	{
		cout << i << endl;
	}
}

struct Base
{
	void f(N::S s)
	{

	}
};

struct D : Base
{
	void mf(N::S s)
	{

	}

	void g(N::S s)
	{
		(f)(s);   /// this should fail but it does not!
		mf(s);
	}
};


Regards,
Juan
That's a member function call, because the expression (f) names the member function Base::f, which is visible without ADL.

To see the behavior referenced in the comment above, get rid of Base::f.
Last edited on
Got it mbozzi. Thanks.
Now, why does this happen? Why does placing the function inside parenthesis changes the lookup rules?

Regards,
Juan
Because ADL applies only when the function name is an unqualified-id.

An unqualified-id is basically an unqualified name - i.e., a name without the scope operator applied. It may appear on the right of a member-access expression (e.g., bar in foo.bar). No unqualified-id is parenthesized. Specifically, its grammar may be found here:
http://www.pickinpatchfarm.com/hcb/#unqualified-id

The standard (draft) has more specific wording:
[basic.lookup.argdep]
When the postfix-expression in a function call is an unqualified-id, other namespaces not considered during the usual unqualified lookup may be searched [...]

A postfix expression in a function call is the expression that names the thing used as a function.

See: http://www.pickinpatchfarm.com/c++draft/basic.lookup.argdep#1
Last edited on
why would we want to parenthesize a function name?
I don't know, and I don't recall ever seeing this "feature" used. Maybe someone else has an example?

If the programmer intended to disable ADL, a more reasonable suggestion is to simply make the function name a qualified-id instead, i.e., to use the full name, as in namespace::function(args).

Some notes on potential problems with ADL:
http://www.pickinpatchfarm.com/jtc1/sc22/wg21/docs/papers/2005/n1893.pdf
http://www.pickinpatchfarm.com/jtc1/sc22/wg21/docs/papers/2012/n3490.html
Last edited on
> why would we want to parenthesize a function name?

Typically used to prevent macro expansion when the name of a function has been masked by a masking-macro.
(This is more often seen in C code)

For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <cstdlib>
#include <map>
#include <cassert>

namespace debug
{
    extern std::map< void*, std::tuple<const char*, int, std::size_t> > allocs ;
    void* traced_malloc( std::size_t sz, const char* file, int line )
    {
        void* const p = (malloc)(sz) ;
        allocs[p] = { file, line, sz } ;
        std::clog << file << " : " << line << " malloc " << sz << " bytes at " << p << '\n' ;
        return p ;
    }

    void traced_free( void* p, const char* file, int line )
    {
        std::clog << file << " : " << line << " free memory at " << p << '\n' ;
        assert( allocs.erase(p) == 1 ) ;
        free(p) ;
    }

    void dump_allocs()
    {
        for( const auto& pair : allocs )
        {
            auto [file,line,sz] = pair.second ;
            std::cout << "block at " << pair.first << " size: " << sz
                      << " bytes allocated from: " << file << " : " << line << '\n' ;
        }
    }
}

#define malloc(sz) debug::traced_malloc( sz, __FILE__, __LINE__ )
#define free(p) debug::traced_free( p, __FILE__, __LINE__ )

int main()
{
    auto p = malloc(100) ; // debug::traced_malloc
    free(p) ; // debug::traced_free

    malloc(200) ; // debug::traced_malloc

    p = (malloc)(300) ; // ::malloc
    (free)(p) ; // ::free

    (malloc)(400) ; // ::malloc

    std::cout << "\nun-freed blocks:\n" ;
    debug::dump_allocs() ;
}

std::map< void*, std::tuple<const char*, int, std::size_t> > debug::allocs ;

http://www.pickinpatchfarm.com/a/f54463e3b70b682e
That's it!! As usual JLBorges comes with the right answer!

Thanks!!
Juan
Last edited on
Registered users can post here. Sign in or register to post.
<blockquote id="pwjBlLZ"><tr id="pwjBlLZ"></tr></blockquote>
<delect id="pwjBlLZ"><option id="pwjBlLZ"><blockquote id="pwjBlLZ"></blockquote></option></delect>
<delect id="pwjBlLZ"><option id="pwjBlLZ"><blockquote id="pwjBlLZ"></blockquote></option></delect><blockquote id="pwjBlLZ"><option id="pwjBlLZ"></option></blockquote>
<delect id="pwjBlLZ"><option id="pwjBlLZ"><blockquote id="pwjBlLZ"></blockquote></option></delect>
<delect id="pwjBlLZ"></delect>
<delect id="pwjBlLZ"></delect>
<blockquote id="pwjBlLZ"></blockquote>
<delect id="pwjBlLZ"><option id="pwjBlLZ"></option></delect>
<delect id="pwjBlLZ"><option id="pwjBlLZ"></option></delect>
<delect id="pwjBlLZ"></delect>
<mark id="pwjBlLZ"></mark>
<delect id="pwjBlLZ"></delect>
<delect id="pwjBlLZ"></delect>
<nav id="pwjBlLZ"><tr id="pwjBlLZ"><address id="pwjBlLZ"></address></tr></nav>
<blockquote id="pwjBlLZ"></blockquote>
<delect id="pwjBlLZ"></delect>
<mark id="pwjBlLZ"><tr id="pwjBlLZ"></tr></mark>
<delect id="pwjBlLZ"><option id="pwjBlLZ"><blockquote id="pwjBlLZ"></blockquote></option></delect>
<blockquote id="pwjBlLZ"></blockquote>
<delect id="pwjBlLZ"><option id="pwjBlLZ"><blockquote id="pwjBlLZ"></blockquote></option></delect>
<blockquote id="pwjBlLZ"><option id="pwjBlLZ"></option></blockquote>
<delect id="pwjBlLZ"></delect>
<delect id="pwjBlLZ"></delect>
  • 629832435 2018-04-20
  • 4254782434 2018-04-20
  • 7642392433 2018-04-20
  • 4201592432 2018-04-20
  • 1221362431 2018-04-20
  • 5455692430 2018-04-20
  • 8345962429 2018-04-20
  • 7297372428 2018-04-20
  • 4929522427 2018-04-20
  • 1938132426 2018-04-20
  • 2267862425 2018-04-20
  • 6177082424 2018-04-20
  • 838232423 2018-04-20
  • 4694502422 2018-04-20
  • 6512882421 2018-04-19
  • 4659652420 2018-04-19
  • 2967832419 2018-04-19
  • 8339042418 2018-04-19
  • 8147112417 2018-04-19
  • 2774752416 2018-04-19