Generic lambda vs generic function give different behaviour The Next CEO of Stack OverflowWhat is a lambda (function)?What is the difference between #include <filename> and #include “filename”?What are the differences between a pointer variable and a reference variable in C++?What is the difference between a 'closure' and a 'lambda'?Why are Python lambdas useful?Distinct() with lambda?list comprehension vs. lambda + filterWhat is a lambda expression in C++11?Calling `this` member function from generic lambda - clang vs gccConstructing std::function argument from lambda

How do we know the LHC results are robust?

Why Were Madagascar and New Zealand Discovered So Late?

Is it okay to store user locations?

How easy is it to start Magic from scratch?

How can I quit an app using Terminal?

Can the Reverse Gravity spell affect the Meteor Swarm spell?

Why does standard notation not preserve intervals (visually)

A pseudo-riley?

Is it a good idea to use COLUMN AS (left([Another_Column],(4)) instead of LEFT in the select?

What's the point of interval inversion?

Was a professor correct to chastise me for writing "Prof. X" rather than "Professor X"?

Customer Requests (Sometimes) Drive Me Bonkers!

Would this house-rule that treats advantage as a +1 to the roll instead (and disadvantage as -1) and allows them to stack be balanced?

Whats the best way to handle refactoring a big file?

How do scammers retract money, while you can’t?

Trouble understanding the speech of overseas colleagues

How long to clear the 'suck zone' of a turbofan after start is initiated?

Implement the Thanos sorting algorithm

The King's new dress

Increase performance creating Mandelbrot set in python

Describing a person. What needs to be mentioned?

When did Lisp start using symbols for arithmetic?

Anatomically Correct Strange Women In Ponds Distributing Swords

Why didn't Theresa May consult with Parliament before negotiating a deal with the EU?



Generic lambda vs generic function give different behaviour



The Next CEO of Stack OverflowWhat is a lambda (function)?What is the difference between #include <filename> and #include “filename”?What are the differences between a pointer variable and a reference variable in C++?What is the difference between a 'closure' and a 'lambda'?Why are Python lambdas useful?Distinct() with lambda?list comprehension vs. lambda + filterWhat is a lambda expression in C++11?Calling `this` member function from generic lambda - clang vs gccConstructing std::function argument from lambda










14















Take following code as an example



#include <algorithm>

namespace baz
template<class T>
void sort(T&&)


namespace boot
const auto sort = [](auto &&);


void foo ()
using namespace std;
using namespace baz;
sort(1);


void bar()
using namespace std;
using namespace boot;
sort(1);



I expected that since foo compiled, then bar shall compile as well. To my surprise, the foo compiles correctly and bar has problem with ambiguous call to sort function. Am I doing something illegal here or this is proper way compiler should behave? If so, why is it so different. I though generic lambda can be treated as syntactic sugar for generic function.



live example










share|improve this question



















  • 5





    Lambdas do not participate in ADL

    – Guillaume Racicot
    2 days ago






  • 10





    This isn't ADL. An int argument doesn't come from any namespace.

    – chris
    2 days ago






  • 4





    Should this really be ambiguous, though? std::sort() doesn't take 1 parameter as input, it takes at least 2, so why is the compiler even considering it as a candidate for a call that passes only 1 parameter value?

    – Remy Lebeau
    2 days ago












  • There must be something about the extra layer of indirection that the lambda introduces. With the first example, the call is made to ::baz::sort, but in the second example, it would have to find ::boot::mystery_lambda_type::operator(). That extra step might be what causes std::sort to be considered first. I don't have the standard in front of me so can't be sure about this.

    – alter igel
    2 days ago















14















Take following code as an example



#include <algorithm>

namespace baz
template<class T>
void sort(T&&)


namespace boot
const auto sort = [](auto &&);


void foo ()
using namespace std;
using namespace baz;
sort(1);


void bar()
using namespace std;
using namespace boot;
sort(1);



I expected that since foo compiled, then bar shall compile as well. To my surprise, the foo compiles correctly and bar has problem with ambiguous call to sort function. Am I doing something illegal here or this is proper way compiler should behave? If so, why is it so different. I though generic lambda can be treated as syntactic sugar for generic function.



live example










share|improve this question



















  • 5





    Lambdas do not participate in ADL

    – Guillaume Racicot
    2 days ago






  • 10





    This isn't ADL. An int argument doesn't come from any namespace.

    – chris
    2 days ago






  • 4





    Should this really be ambiguous, though? std::sort() doesn't take 1 parameter as input, it takes at least 2, so why is the compiler even considering it as a candidate for a call that passes only 1 parameter value?

    – Remy Lebeau
    2 days ago












  • There must be something about the extra layer of indirection that the lambda introduces. With the first example, the call is made to ::baz::sort, but in the second example, it would have to find ::boot::mystery_lambda_type::operator(). That extra step might be what causes std::sort to be considered first. I don't have the standard in front of me so can't be sure about this.

    – alter igel
    2 days ago













14












14








14


1






Take following code as an example



#include <algorithm>

namespace baz
template<class T>
void sort(T&&)


namespace boot
const auto sort = [](auto &&);


void foo ()
using namespace std;
using namespace baz;
sort(1);


void bar()
using namespace std;
using namespace boot;
sort(1);



I expected that since foo compiled, then bar shall compile as well. To my surprise, the foo compiles correctly and bar has problem with ambiguous call to sort function. Am I doing something illegal here or this is proper way compiler should behave? If so, why is it so different. I though generic lambda can be treated as syntactic sugar for generic function.



live example










share|improve this question
















Take following code as an example



#include <algorithm>

namespace baz
template<class T>
void sort(T&&)


namespace boot
const auto sort = [](auto &&);


void foo ()
using namespace std;
using namespace baz;
sort(1);


void bar()
using namespace std;
using namespace boot;
sort(1);



I expected that since foo compiled, then bar shall compile as well. To my surprise, the foo compiles correctly and bar has problem with ambiguous call to sort function. Am I doing something illegal here or this is proper way compiler should behave? If so, why is it so different. I though generic lambda can be treated as syntactic sugar for generic function.



live example







c++ lambda c++14






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 days ago







bartop

















asked 2 days ago









bartopbartop

3,2601031




3,2601031







  • 5





    Lambdas do not participate in ADL

    – Guillaume Racicot
    2 days ago






  • 10





    This isn't ADL. An int argument doesn't come from any namespace.

    – chris
    2 days ago






  • 4





    Should this really be ambiguous, though? std::sort() doesn't take 1 parameter as input, it takes at least 2, so why is the compiler even considering it as a candidate for a call that passes only 1 parameter value?

    – Remy Lebeau
    2 days ago












  • There must be something about the extra layer of indirection that the lambda introduces. With the first example, the call is made to ::baz::sort, but in the second example, it would have to find ::boot::mystery_lambda_type::operator(). That extra step might be what causes std::sort to be considered first. I don't have the standard in front of me so can't be sure about this.

    – alter igel
    2 days ago












  • 5





    Lambdas do not participate in ADL

    – Guillaume Racicot
    2 days ago






  • 10





    This isn't ADL. An int argument doesn't come from any namespace.

    – chris
    2 days ago






  • 4





    Should this really be ambiguous, though? std::sort() doesn't take 1 parameter as input, it takes at least 2, so why is the compiler even considering it as a candidate for a call that passes only 1 parameter value?

    – Remy Lebeau
    2 days ago












  • There must be something about the extra layer of indirection that the lambda introduces. With the first example, the call is made to ::baz::sort, but in the second example, it would have to find ::boot::mystery_lambda_type::operator(). That extra step might be what causes std::sort to be considered first. I don't have the standard in front of me so can't be sure about this.

    – alter igel
    2 days ago







5




5





Lambdas do not participate in ADL

– Guillaume Racicot
2 days ago





Lambdas do not participate in ADL

– Guillaume Racicot
2 days ago




10




10





This isn't ADL. An int argument doesn't come from any namespace.

– chris
2 days ago





This isn't ADL. An int argument doesn't come from any namespace.

– chris
2 days ago




4




4





Should this really be ambiguous, though? std::sort() doesn't take 1 parameter as input, it takes at least 2, so why is the compiler even considering it as a candidate for a call that passes only 1 parameter value?

– Remy Lebeau
2 days ago






Should this really be ambiguous, though? std::sort() doesn't take 1 parameter as input, it takes at least 2, so why is the compiler even considering it as a candidate for a call that passes only 1 parameter value?

– Remy Lebeau
2 days ago














There must be something about the extra layer of indirection that the lambda introduces. With the first example, the call is made to ::baz::sort, but in the second example, it would have to find ::boot::mystery_lambda_type::operator(). That extra step might be what causes std::sort to be considered first. I don't have the standard in front of me so can't be sure about this.

– alter igel
2 days ago





There must be something about the extra layer of indirection that the lambda introduces. With the first example, the call is made to ::baz::sort, but in the second example, it would have to find ::boot::mystery_lambda_type::operator(). That extra step might be what causes std::sort to be considered first. I don't have the standard in front of me so can't be sure about this.

– alter igel
2 days ago












1 Answer
1






active

oldest

votes


















16














The problem here is not that the call to sort is ambiguous, but that the name sort is ambiguous. Name lookup happens before overload resolution.



I believe the relevant section is [basic.lookup]/1, specifically




[…] The declarations found by name lookup shall either all denote the same entity or shall all denote functions or function templates; in the latter case, the declarations are said to form a set of overloaded functions ([over.load]). […]




In your case, the name sort denotes both, the object boot::sort as well as the set of overloaded functions std::sort. Therefore, name lookup fails.



Your code is really no different from if you had written, for example



namespace baz 
int a;


namespace boot
int a;


void foo()
using namespace baz;
using namespace boot;
a = 42; // error: reference to 'a' is ambiguous



Try it out here; compare this to a case that actually has an ambiguous function call; note how the error message is the same as in your case, specifically referring to the name itself being ambiguous rather than the function call.






share|improve this answer




















  • 1





    I think this is actually the right answer. And I would like to add that if both the template function sort and the lambda sort were declared in the same namespace, it would be an error. You cannot have a function and non-function with the same name in the same namespace. So there could never be an overload set that has both true functions and function-like objects.

    – Mike
    yesterday











  • Seems like a right answet to me. If there is something that can be done to workaround my problem I would be thankful for comment/answer edit.

    – bartop
    yesterday






  • 1





    @Scheff indeed, I must've mixed up the URLs somehow. Should be fixed now. Thanks for pointing that out!

    – Michael Kenzel
    yesterday












  • @bartop can you not just remove the using directives and/or use fully-qualified names, e.g., baz::sort!?

    – Michael Kenzel
    yesterday












  • @MichaelKenzel Sure can, and I do it currently. Even though I still wonder if there is different way to avoid this ambiguity

    – bartop
    yesterday











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55367269%2fgeneric-lambda-vs-generic-function-give-different-behaviour%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









16














The problem here is not that the call to sort is ambiguous, but that the name sort is ambiguous. Name lookup happens before overload resolution.



I believe the relevant section is [basic.lookup]/1, specifically




[…] The declarations found by name lookup shall either all denote the same entity or shall all denote functions or function templates; in the latter case, the declarations are said to form a set of overloaded functions ([over.load]). […]




In your case, the name sort denotes both, the object boot::sort as well as the set of overloaded functions std::sort. Therefore, name lookup fails.



Your code is really no different from if you had written, for example



namespace baz 
int a;


namespace boot
int a;


void foo()
using namespace baz;
using namespace boot;
a = 42; // error: reference to 'a' is ambiguous



Try it out here; compare this to a case that actually has an ambiguous function call; note how the error message is the same as in your case, specifically referring to the name itself being ambiguous rather than the function call.






share|improve this answer




















  • 1





    I think this is actually the right answer. And I would like to add that if both the template function sort and the lambda sort were declared in the same namespace, it would be an error. You cannot have a function and non-function with the same name in the same namespace. So there could never be an overload set that has both true functions and function-like objects.

    – Mike
    yesterday











  • Seems like a right answet to me. If there is something that can be done to workaround my problem I would be thankful for comment/answer edit.

    – bartop
    yesterday






  • 1





    @Scheff indeed, I must've mixed up the URLs somehow. Should be fixed now. Thanks for pointing that out!

    – Michael Kenzel
    yesterday












  • @bartop can you not just remove the using directives and/or use fully-qualified names, e.g., baz::sort!?

    – Michael Kenzel
    yesterday












  • @MichaelKenzel Sure can, and I do it currently. Even though I still wonder if there is different way to avoid this ambiguity

    – bartop
    yesterday















16














The problem here is not that the call to sort is ambiguous, but that the name sort is ambiguous. Name lookup happens before overload resolution.



I believe the relevant section is [basic.lookup]/1, specifically




[…] The declarations found by name lookup shall either all denote the same entity or shall all denote functions or function templates; in the latter case, the declarations are said to form a set of overloaded functions ([over.load]). […]




In your case, the name sort denotes both, the object boot::sort as well as the set of overloaded functions std::sort. Therefore, name lookup fails.



Your code is really no different from if you had written, for example



namespace baz 
int a;


namespace boot
int a;


void foo()
using namespace baz;
using namespace boot;
a = 42; // error: reference to 'a' is ambiguous



Try it out here; compare this to a case that actually has an ambiguous function call; note how the error message is the same as in your case, specifically referring to the name itself being ambiguous rather than the function call.






share|improve this answer




















  • 1





    I think this is actually the right answer. And I would like to add that if both the template function sort and the lambda sort were declared in the same namespace, it would be an error. You cannot have a function and non-function with the same name in the same namespace. So there could never be an overload set that has both true functions and function-like objects.

    – Mike
    yesterday











  • Seems like a right answet to me. If there is something that can be done to workaround my problem I would be thankful for comment/answer edit.

    – bartop
    yesterday






  • 1





    @Scheff indeed, I must've mixed up the URLs somehow. Should be fixed now. Thanks for pointing that out!

    – Michael Kenzel
    yesterday












  • @bartop can you not just remove the using directives and/or use fully-qualified names, e.g., baz::sort!?

    – Michael Kenzel
    yesterday












  • @MichaelKenzel Sure can, and I do it currently. Even though I still wonder if there is different way to avoid this ambiguity

    – bartop
    yesterday













16












16








16







The problem here is not that the call to sort is ambiguous, but that the name sort is ambiguous. Name lookup happens before overload resolution.



I believe the relevant section is [basic.lookup]/1, specifically




[…] The declarations found by name lookup shall either all denote the same entity or shall all denote functions or function templates; in the latter case, the declarations are said to form a set of overloaded functions ([over.load]). […]




In your case, the name sort denotes both, the object boot::sort as well as the set of overloaded functions std::sort. Therefore, name lookup fails.



Your code is really no different from if you had written, for example



namespace baz 
int a;


namespace boot
int a;


void foo()
using namespace baz;
using namespace boot;
a = 42; // error: reference to 'a' is ambiguous



Try it out here; compare this to a case that actually has an ambiguous function call; note how the error message is the same as in your case, specifically referring to the name itself being ambiguous rather than the function call.






share|improve this answer















The problem here is not that the call to sort is ambiguous, but that the name sort is ambiguous. Name lookup happens before overload resolution.



I believe the relevant section is [basic.lookup]/1, specifically




[…] The declarations found by name lookup shall either all denote the same entity or shall all denote functions or function templates; in the latter case, the declarations are said to form a set of overloaded functions ([over.load]). […]




In your case, the name sort denotes both, the object boot::sort as well as the set of overloaded functions std::sort. Therefore, name lookup fails.



Your code is really no different from if you had written, for example



namespace baz 
int a;


namespace boot
int a;


void foo()
using namespace baz;
using namespace boot;
a = 42; // error: reference to 'a' is ambiguous



Try it out here; compare this to a case that actually has an ambiguous function call; note how the error message is the same as in your case, specifically referring to the name itself being ambiguous rather than the function call.







share|improve this answer














share|improve this answer



share|improve this answer








edited yesterday

























answered yesterday









Michael KenzelMichael Kenzel

5,43811122




5,43811122







  • 1





    I think this is actually the right answer. And I would like to add that if both the template function sort and the lambda sort were declared in the same namespace, it would be an error. You cannot have a function and non-function with the same name in the same namespace. So there could never be an overload set that has both true functions and function-like objects.

    – Mike
    yesterday











  • Seems like a right answet to me. If there is something that can be done to workaround my problem I would be thankful for comment/answer edit.

    – bartop
    yesterday






  • 1





    @Scheff indeed, I must've mixed up the URLs somehow. Should be fixed now. Thanks for pointing that out!

    – Michael Kenzel
    yesterday












  • @bartop can you not just remove the using directives and/or use fully-qualified names, e.g., baz::sort!?

    – Michael Kenzel
    yesterday












  • @MichaelKenzel Sure can, and I do it currently. Even though I still wonder if there is different way to avoid this ambiguity

    – bartop
    yesterday












  • 1





    I think this is actually the right answer. And I would like to add that if both the template function sort and the lambda sort were declared in the same namespace, it would be an error. You cannot have a function and non-function with the same name in the same namespace. So there could never be an overload set that has both true functions and function-like objects.

    – Mike
    yesterday











  • Seems like a right answet to me. If there is something that can be done to workaround my problem I would be thankful for comment/answer edit.

    – bartop
    yesterday






  • 1





    @Scheff indeed, I must've mixed up the URLs somehow. Should be fixed now. Thanks for pointing that out!

    – Michael Kenzel
    yesterday












  • @bartop can you not just remove the using directives and/or use fully-qualified names, e.g., baz::sort!?

    – Michael Kenzel
    yesterday












  • @MichaelKenzel Sure can, and I do it currently. Even though I still wonder if there is different way to avoid this ambiguity

    – bartop
    yesterday







1




1





I think this is actually the right answer. And I would like to add that if both the template function sort and the lambda sort were declared in the same namespace, it would be an error. You cannot have a function and non-function with the same name in the same namespace. So there could never be an overload set that has both true functions and function-like objects.

– Mike
yesterday





I think this is actually the right answer. And I would like to add that if both the template function sort and the lambda sort were declared in the same namespace, it would be an error. You cannot have a function and non-function with the same name in the same namespace. So there could never be an overload set that has both true functions and function-like objects.

– Mike
yesterday













Seems like a right answet to me. If there is something that can be done to workaround my problem I would be thankful for comment/answer edit.

– bartop
yesterday





Seems like a right answet to me. If there is something that can be done to workaround my problem I would be thankful for comment/answer edit.

– bartop
yesterday




1




1





@Scheff indeed, I must've mixed up the URLs somehow. Should be fixed now. Thanks for pointing that out!

– Michael Kenzel
yesterday






@Scheff indeed, I must've mixed up the URLs somehow. Should be fixed now. Thanks for pointing that out!

– Michael Kenzel
yesterday














@bartop can you not just remove the using directives and/or use fully-qualified names, e.g., baz::sort!?

– Michael Kenzel
yesterday






@bartop can you not just remove the using directives and/or use fully-qualified names, e.g., baz::sort!?

– Michael Kenzel
yesterday














@MichaelKenzel Sure can, and I do it currently. Even though I still wonder if there is different way to avoid this ambiguity

– bartop
yesterday





@MichaelKenzel Sure can, and I do it currently. Even though I still wonder if there is different way to avoid this ambiguity

– bartop
yesterday



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55367269%2fgeneric-lambda-vs-generic-function-give-different-behaviour%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Sum ergo cogito? 1 nng

419 nièngy_Soadمي 19bal1.5o_g

Queiggey Chernihivv 9NnOo i Zw X QqKk LpB