Topic: Extend an ADL search algorithm


Author: Denis Kotov <redradist@gmail.com>
Date: Tue, 9 Oct 2018 11:11:13 -0700 (PDT)
Raw View
------=_Part_2221_237128896.1539108673494
Content-Type: multipart/alternative;
 boundary="----=_Part_2222_644902254.1539108673494"

------=_Part_2222_644902254.1539108673494
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hello everyone,

I have prepared the proposal for extending an ADL search algorithm:

*Propousal for extension methods like.* Lets consider the following example=
:

    namespace DeviceManager {
      class Device {
        public:
          ... // Other member functions
          uint32_t getId() const {
            return id_;
          }
        private:
          ... // Other member variables
          uint32_t id_;
      };

      using DeviceList =3D std::vector&lt;Device&gt;;

      Device mergeDeviceInfo(const Device & _first, const Device & _second)=
=20
{
        ... // Implementation
      }
    }

    int main() {
      DeviceManager::DeviceList deviceList;
      ... // Some work
      auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),=20
deviceList.end(), [=3D] {
        ... // Some first creteria
      });
      auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),=20
deviceList.end(), [=3D] {
        ... // Some second creteria
      });
      if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=3D=
=20
foundDeviceIter1) {
        DeviceManager::Device mergedDevice =3D=20
DeviceManager::mergeDeviceInfo(*foundDeviceIter0, *foundDeviceIter1);
        ... // Some other work
      }
    }

As you can see in case one helper function it is easy to manipulate and use=
=20
it, but in case of a lot of functions it would be better to support some=20
kind of extension methods:

namespace DeviceManager {
      class Device {
        public:
          ... // Other member functions
          uint32_t getId() const {
            return id_;
          }
        private:
          ... // Other member variables
          uint32_t id_;
      };

      using DeviceList =3D std::vector&lt;Device&gt;;

      // 1. If it is called by reference type prefer this overload function
      Device mergeDeviceInfo(const Device & _first, const Device & _second)=
=20
{
        ... // Implementation
      }
      // 2. If it is called by pointer type prefer this overload function
      Device mergeDeviceInfo(const Device * _firstPtr, const Device *=20
_secondPtr) {
        ... // Implementation
      }
    }

    int main() {
      DeviceManager::DeviceList deviceList;
      ... // Some work
      auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),=20
deviceList.end(), [=3D] {
        ... // Some first creteria
      });
      auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),=20
deviceList.end(), [=3D] {
        ... // Some second creteria
      });
      if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=3D=
=20
foundDeviceIter1) {
        // 1. Overload function for references if called
        // ADL will search in dependent scopes also for calling functions=
=20
by object reference
        DeviceManager::Device & firstFoundDevice =3D *foundDeviceIter0;
        DeviceManager::Device & secondFoundDevice =3D *foundDeviceIter1;
        DeviceManager::Device mergedDevice =3D=20
firstFoundDevice.mergeDeviceInfo(secondFoundDevice);

        // 2. Overload function for pointers if called
        // ADL will search in dependent scopes lso for calling functions by=
=20
object pointer
        DeviceManager::Device mergedDevice =3D=20
foundDeviceIter0->mergeDeviceInfo(*foundDeviceIter1);
        ... // Some other work
      }
    }

*Propousal for extension of ADL on template parameter.* Lets consider the=
=20
following example:

    namespace IPCBus {
      class IClient {
        public:
          ... // Other member functions
          template &lt;typename TClient&gt;
          static std::shared_ptr&lt;IClient&gt; buildClient() {
            auto client =3D std::shared_ptr(new TClient);
            ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE SKIPED=
=20
!!
            return client;
          }
        protected:
          Client() =3D default;
      };
    }  // namespace IPCBus

    class RealClient : public IClient {
      public:
       RealClient()
         : IClient() {
       }
    };

    using namespace std;

    int main() {
      auto realClient =3D make_shared&lt;RealClient&gt;();
      // WE MISSED THE VERY IMPORTANT STEPS IN CREATION OF OBJECT !!
    }

As you can see in case one helper function it is easy to manipulate and use=
=20
it, but in case of a lot of functions it would be better to support some=20
kind of extension methods:

    namespace IPCBus {
      class IClient {
        public:
          ... // Other member functions
          template &lt;typename TClient&gt;
          static std::shared_ptr&lt;IClient&gt; buildClient() {
            auto client =3D std::shared_ptr(new TClient);
            ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE SKIPED=
=20
!!
            return client;
          }
        protected:
          Client() =3D default;
      };

      template &lt;typename T, typename ... TArgs&gt;
      std::shared_ptr&lt;T&gt; make_shared(TArgs&&... _args) {
        return IClient::buildClient(std::forward&lt;TArgs&gt;(_args)...);
      }
    }  // namespace IPCBus

    class RealClient : public IClient {
      public:
       RealClient()
         : IClient() {
       }
    };

    using namespace std;

    int main() {
      auto realClient =3D make_shared&lt;RealClient&gt;();
      // We use our own version of make_shared that is delegate creation of=
=20
object to builder method
      // Cool !!
    }

As *Herb Sutter* said at *CppCon 2017: Herb Sutter =E2=80=9CMeta: Thoughts =
on=20
generative C++=E2=80=9D*:
"Abstraction are hiders by definition. If they did not do this they are=20
useless ..."
"It's not the problem. It is the point."

I see this suggestion to extend *ADL* search on caller object and on=20
template parameter as simplifier for Library Writters and also General=20
Programmers

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/799e13cb-4354-4ffe-8568-276e1cbfe61c%40isocpp.or=
g.

------=_Part_2222_644902254.1539108673494
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: base64

PGRpdiBkaXI9Imx0ciI+PGRpdj5IZWxsbyBldmVyeW9uZSw8L2Rpdj48ZGl2Pjxicj48L2Rpdj48
ZGl2PkkgaGF2ZSBwcmVwYXJlZCB0aGUgcHJvcG9zYWwgZm9yIGV4dGVuZGluZyBhbiBBREwgc2Vh
cmNoIGFsZ29yaXRobTo8L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PjxiPlByb3BvdXNhbCBmb3Ig
ZXh0ZW5zaW9uIG1ldGhvZHMgbGlrZS48L2I+IExldHMgY29uc2lkZXIgdGhlIGZvbGxvd2luZyBl
eGFtcGxlOjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+wqDCoMKgIG5hbWVzcGFjZSBEZXZpY2VN
YW5hZ2VyIHs8YnI+wqDCoMKgwqDCoCBjbGFzcyBEZXZpY2Ugezxicj7CoMKgwqDCoMKgwqDCoCBw
dWJsaWM6PGJyPsKgwqDCoMKgwqDCoMKgwqDCoCAuLi4gLy8gT3RoZXIgbWVtYmVyIGZ1bmN0aW9u
czxicj7CoMKgwqDCoMKgwqDCoMKgwqAgdWludDMyX3QgZ2V0SWQoKSBjb25zdCB7PGJyPsKgwqDC
oMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIGlkXzs8YnI+wqDCoMKgwqDCoMKgwqDCoMKgIH08YnI+
wqDCoMKgwqDCoMKgwqAgcHJpdmF0ZTo8YnI+wqDCoMKgwqDCoMKgwqDCoMKgIC4uLiAvLyBPdGhl
ciBtZW1iZXIgdmFyaWFibGVzPGJyPsKgwqDCoMKgwqDCoMKgwqDCoCB1aW50MzJfdCBpZF87PGJy
PsKgwqDCoMKgwqAgfTs8YnI+PGJyPsKgwqDCoMKgwqAgdXNpbmcgRGV2aWNlTGlzdCA9IHN0ZDo6
dmVjdG9yJmFtcDtsdDtEZXZpY2UmYW1wO2d0Ozs8YnI+PGJyPsKgwqDCoMKgwqAgRGV2aWNlIG1l
cmdlRGV2aWNlSW5mbyhjb25zdCBEZXZpY2UgJmFtcDsgX2ZpcnN0LCBjb25zdCBEZXZpY2UgJmFt
cDsgX3NlY29uZCkgezxicj7CoMKgwqDCoMKgwqDCoCAuLi4gLy8gSW1wbGVtZW50YXRpb248YnI+
wqDCoMKgwqDCoCB9PGJyPsKgwqDCoCB9PGJyPjxicj7CoMKgwqAgaW50IG1haW4oKSB7PGJyPsKg
wqDCoMKgwqAgRGV2aWNlTWFuYWdlcjo6RGV2aWNlTGlzdCBkZXZpY2VMaXN0Ozxicj7CoMKgwqDC
oMKgIC4uLiAvLyBTb21lIHdvcms8YnI+wqDCoMKgwqDCoCBhdXRvIGZvdW5kRGV2aWNlSXRlcjAg
PSBzdGQ6OmZpbmRfaWYoZGV2aWNlTGlzdC5iZWdpbigpLCBkZXZpY2VMaXN0LmVuZCgpLCBbPV0g
ezxicj7CoMKgwqDCoMKgwqDCoCAuLi4gLy8gU29tZSBmaXJzdCBjcmV0ZXJpYTxicj7CoMKgwqDC
oMKgIH0pOzxicj7CoMKgwqDCoMKgIGF1dG8gZm91bmREZXZpY2VJdGVyMSA9IHN0ZDo6ZmluZF9p
ZihkZXZpY2VMaXN0LmJlZ2luKCksIGRldmljZUxpc3QuZW5kKCksIFs9XSB7PGJyPsKgwqDCoMKg
wqDCoMKgIC4uLiAvLyBTb21lIHNlY29uZCBjcmV0ZXJpYTxicj7CoMKgwqDCoMKgIH0pOzxicj7C
oMKgwqDCoMKgIGlmIChkZXZpY2VMaXN0LmVuZCgpICE9IGZvdW5kRGV2aWNlSXRlcjAgJmFtcDsm
YW1wOyBkZXZpY2VMaXN0LmVuZCgpICE9IGZvdW5kRGV2aWNlSXRlcjEpIHs8YnI+wqDCoMKgwqDC
oMKgwqAgRGV2aWNlTWFuYWdlcjo6RGV2aWNlIG1lcmdlZERldmljZSA9IERldmljZU1hbmFnZXI6
Om1lcmdlRGV2aWNlSW5mbygqZm91bmREZXZpY2VJdGVyMCwgKmZvdW5kRGV2aWNlSXRlcjEpOzxi
cj7CoMKgwqDCoMKgwqDCoCAuLi4gLy8gU29tZSBvdGhlciB3b3JrPGJyPsKgwqDCoMKgwqAgfTxi
cj7CoMKgwqAgfTwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+QXMgeW91IGNhbiBzZWUgaW4gY2Fz
ZSBvbmUgaGVscGVyIGZ1bmN0aW9uIGl0IGlzIGVhc3kgdG8gbWFuaXB1bGF0ZSBhbmQgdXNlIGl0
LCBidXQgaW4gY2FzZSBvZiBhIGxvdCBvZiBmdW5jdGlvbnMgaXQgd291bGQgYmUgYmV0dGVyIHRv
IHN1cHBvcnQgc29tZSBraW5kIG9mIGV4dGVuc2lvbiBtZXRob2RzOjwvZGl2PjxkaXY+PGJyPjwv
ZGl2PjxkaXY+bmFtZXNwYWNlIERldmljZU1hbmFnZXIgezxicj7CoMKgwqDCoMKgIGNsYXNzIERl
dmljZSB7PGJyPsKgwqDCoMKgwqDCoMKgIHB1YmxpYzo8YnI+wqDCoMKgwqDCoMKgwqDCoMKgIC4u
LiAvLyBPdGhlciBtZW1iZXIgZnVuY3Rpb25zPGJyPsKgwqDCoMKgwqDCoMKgwqDCoCB1aW50MzJf
dCBnZXRJZCgpIGNvbnN0IHs8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gaWRfOzxi
cj7CoMKgwqDCoMKgwqDCoMKgwqAgfTxicj7CoMKgwqDCoMKgwqDCoCBwcml2YXRlOjxicj7CoMKg
wqDCoMKgwqDCoMKgwqAgLi4uIC8vIE90aGVyIG1lbWJlciB2YXJpYWJsZXM8YnI+wqDCoMKgwqDC
oMKgwqDCoMKgIHVpbnQzMl90IGlkXzs8YnI+wqDCoMKgwqDCoCB9Ozxicj48YnI+wqDCoMKgwqDC
oCB1c2luZyBEZXZpY2VMaXN0ID0gc3RkOjp2ZWN0b3ImYW1wO2x0O0RldmljZSZhbXA7Z3Q7Ozxi
cj48YnI+wqDCoMKgwqDCoCAvLyAxLiBJZiBpdCBpcyBjYWxsZWQgYnkgcmVmZXJlbmNlIHR5cGUg
cHJlZmVyIHRoaXMgb3ZlcmxvYWQgZnVuY3Rpb248YnI+wqDCoMKgwqDCoCBEZXZpY2UgbWVyZ2VE
ZXZpY2VJbmZvKGNvbnN0IERldmljZSAmYW1wOyBfZmlyc3QsIGNvbnN0IERldmljZSAmYW1wOyBf
c2Vjb25kKSB7PGJyPsKgwqDCoMKgwqDCoMKgIC4uLiAvLyBJbXBsZW1lbnRhdGlvbjxicj7CoMKg
wqDCoMKgIH08YnI+wqDCoMKgwqDCoCAvLyAyLiBJZiBpdCBpcyBjYWxsZWQgYnkgcG9pbnRlciB0
eXBlIHByZWZlciB0aGlzIG92ZXJsb2FkIGZ1bmN0aW9uPGJyPsKgwqDCoMKgwqAgRGV2aWNlIG1l
cmdlRGV2aWNlSW5mbyhjb25zdCBEZXZpY2UgKiBfZmlyc3RQdHIsIGNvbnN0IERldmljZSAqIF9z
ZWNvbmRQdHIpIHs8YnI+wqDCoMKgwqDCoMKgwqAgLi4uIC8vIEltcGxlbWVudGF0aW9uPGJyPsKg
wqDCoMKgwqAgfTxicj7CoMKgwqAgfTxicj48YnI+wqDCoMKgIGludCBtYWluKCkgezxicj7CoMKg
wqDCoMKgIERldmljZU1hbmFnZXI6OkRldmljZUxpc3QgZGV2aWNlTGlzdDs8YnI+wqDCoMKgwqDC
oCAuLi4gLy8gU29tZSB3b3JrPGJyPsKgwqDCoMKgwqAgYXV0byBmb3VuZERldmljZUl0ZXIwID0g
c3RkOjpmaW5kX2lmKGRldmljZUxpc3QuYmVnaW4oKSwgZGV2aWNlTGlzdC5lbmQoKSwgWz1dIHs8
YnI+wqDCoMKgwqDCoMKgwqAgLi4uIC8vIFNvbWUgZmlyc3QgY3JldGVyaWE8YnI+wqDCoMKgwqDC
oCB9KTs8YnI+wqDCoMKgwqDCoCBhdXRvIGZvdW5kRGV2aWNlSXRlcjEgPSBzdGQ6OmZpbmRfaWYo
ZGV2aWNlTGlzdC5iZWdpbigpLCBkZXZpY2VMaXN0LmVuZCgpLCBbPV0gezxicj7CoMKgwqDCoMKg
wqDCoCAuLi4gLy8gU29tZSBzZWNvbmQgY3JldGVyaWE8YnI+wqDCoMKgwqDCoCB9KTs8YnI+wqDC
oMKgwqDCoCBpZiAoZGV2aWNlTGlzdC5lbmQoKSAhPSBmb3VuZERldmljZUl0ZXIwICZhbXA7JmFt
cDsgZGV2aWNlTGlzdC5lbmQoKSAhPSBmb3VuZERldmljZUl0ZXIxKSB7PGJyPsKgwqDCoMKgwqDC
oMKgIC8vIDEuIE92ZXJsb2FkIGZ1bmN0aW9uIGZvciByZWZlcmVuY2VzIGlmIGNhbGxlZDxicj7C
oMKgwqDCoMKgwqDCoCAvLyBBREwgd2lsbCBzZWFyY2ggaW4gZGVwZW5kZW50IHNjb3BlcyBhbHNv
IGZvciBjYWxsaW5nIGZ1bmN0aW9ucyBieSBvYmplY3QgcmVmZXJlbmNlPGJyPsKgwqDCoMKgwqDC
oMKgIERldmljZU1hbmFnZXI6OkRldmljZSAmYW1wOyBmaXJzdEZvdW5kRGV2aWNlID0gKmZvdW5k
RGV2aWNlSXRlcjA7PGJyPsKgwqDCoMKgwqDCoMKgIERldmljZU1hbmFnZXI6OkRldmljZSAmYW1w
OyBzZWNvbmRGb3VuZERldmljZSA9ICpmb3VuZERldmljZUl0ZXIxOzxicj7CoMKgwqDCoMKgwqDC
oCBEZXZpY2VNYW5hZ2VyOjpEZXZpY2UgbWVyZ2VkRGV2aWNlID0gZmlyc3RGb3VuZERldmljZS5t
ZXJnZURldmljZUluZm8oc2Vjb25kRm91bmREZXZpY2UpOzxicj48YnI+wqDCoMKgwqDCoMKgwqAg
Ly8gMi4gT3ZlcmxvYWQgZnVuY3Rpb24gZm9yIHBvaW50ZXJzIGlmIGNhbGxlZDxicj7CoMKgwqDC
oMKgwqDCoCAvLyBBREwgd2lsbCBzZWFyY2ggaW4gZGVwZW5kZW50IHNjb3BlcyBsc28gZm9yIGNh
bGxpbmcgZnVuY3Rpb25zIGJ5IG9iamVjdCBwb2ludGVyPGJyPsKgwqDCoMKgwqDCoMKgIERldmlj
ZU1hbmFnZXI6OkRldmljZSBtZXJnZWREZXZpY2UgPSBmb3VuZERldmljZUl0ZXIwLSZndDttZXJn
ZURldmljZUluZm8oKmZvdW5kRGV2aWNlSXRlcjEpOzxicj7CoMKgwqDCoMKgwqDCoCAuLi4gLy8g
U29tZSBvdGhlciB3b3JrPGJyPsKgwqDCoMKgwqAgfTxicj7CoMKgwqAgfTwvZGl2PjxkaXY+PGJy
PjwvZGl2PjxkaXY+PGI+UHJvcG91c2FsIGZvciBleHRlbnNpb24gb2YgQURMIG9uIHRlbXBsYXRl
IHBhcmFtZXRlci48L2I+IExldHMgY29uc2lkZXIgdGhlIGZvbGxvd2luZyBleGFtcGxlOjwvZGl2
PjxkaXY+PGJyPjwvZGl2PjxkaXY+wqDCoMKgIG5hbWVzcGFjZSBJUENCdXMgezxicj7CoMKgwqDC
oMKgIGNsYXNzIElDbGllbnQgezxicj7CoMKgwqDCoMKgwqDCoCBwdWJsaWM6PGJyPsKgwqDCoMKg
wqDCoMKgwqDCoCAuLi4gLy8gT3RoZXIgbWVtYmVyIGZ1bmN0aW9uczxicj7CoMKgwqDCoMKgwqDC
oMKgwqAgdGVtcGxhdGUgJmFtcDtsdDt0eXBlbmFtZSBUQ2xpZW50JmFtcDtndDs8YnI+wqDCoMKg
wqDCoMKgwqDCoMKgIHN0YXRpYyBzdGQ6OnNoYXJlZF9wdHImYW1wO2x0O0lDbGllbnQmYW1wO2d0
OyBidWlsZENsaWVudCgpIHs8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdXRvIGNsaWVudCA9
IHN0ZDo6c2hhcmVkX3B0cihuZXcgVENsaWVudCk7PGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg
Li4uIC8vIElNUE9SVEFOVCBUSElOR1MgQUZURVIgSU5JVElBTElaQVRJT04uIENBTk5PVCBCRSBT
S0lQRUQgISE8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gY2xpZW50Ozxicj7CoMKg
wqDCoMKgwqDCoMKgwqAgfTxicj7CoMKgwqDCoMKgwqDCoCBwcm90ZWN0ZWQ6PGJyPsKgwqDCoMKg
wqDCoMKgwqDCoCBDbGllbnQoKSA9IGRlZmF1bHQ7PGJyPsKgwqDCoMKgwqAgfTs8YnI+wqDCoMKg
IH3CoCAvLyBuYW1lc3BhY2UgSVBDQnVzPGJyPjxicj7CoMKgwqAgY2xhc3MgUmVhbENsaWVudCA6
IHB1YmxpYyBJQ2xpZW50IHs8YnI+wqDCoMKgwqDCoCBwdWJsaWM6PGJyPsKgwqDCoMKgwqDCoCBS
ZWFsQ2xpZW50KCk8YnI+wqDCoMKgwqDCoMKgwqDCoCA6IElDbGllbnQoKSB7PGJyPsKgwqDCoMKg
wqDCoCB9PGJyPsKgwqDCoCB9Ozxicj48YnI+wqDCoMKgIHVzaW5nIG5hbWVzcGFjZSBzdGQ7PGJy
Pjxicj7CoMKgwqAgaW50IG1haW4oKSB7PGJyPsKgwqDCoMKgwqAgYXV0byByZWFsQ2xpZW50ID0g
bWFrZV9zaGFyZWQmYW1wO2x0O1JlYWxDbGllbnQmYW1wO2d0OygpOzxicj7CoMKgwqDCoMKgIC8v
IFdFIE1JU1NFRCBUSEUgVkVSWSBJTVBPUlRBTlQgU1RFUFMgSU4gQ1JFQVRJT04gT0YgT0JKRUNU
ICEhPGJyPsKgwqDCoCB9PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5BcyB5b3UgY2FuIHNlZSBp
biBjYXNlIG9uZSBoZWxwZXIgZnVuY3Rpb24gaXQgaXMgZWFzeSB0byBtYW5pcHVsYXRlIGFuZCB1
c2UgaXQsIGJ1dCBpbiBjYXNlIG9mIGEgbG90IG9mIGZ1bmN0aW9ucyBpdCB3b3VsZCBiZSBiZXR0
ZXIgdG8gc3VwcG9ydCBzb21lIGtpbmQgb2YgZXh0ZW5zaW9uIG1ldGhvZHM6PC9kaXY+PGRpdj48
YnI+PC9kaXY+PGRpdj7CoMKgwqAgbmFtZXNwYWNlIElQQ0J1cyB7PGJyPsKgwqDCoMKgwqAgY2xh
c3MgSUNsaWVudCB7PGJyPsKgwqDCoMKgwqDCoMKgIHB1YmxpYzo8YnI+wqDCoMKgwqDCoMKgwqDC
oMKgIC4uLiAvLyBPdGhlciBtZW1iZXIgZnVuY3Rpb25zPGJyPsKgwqDCoMKgwqDCoMKgwqDCoCB0
ZW1wbGF0ZSAmYW1wO2x0O3R5cGVuYW1lIFRDbGllbnQmYW1wO2d0Ozxicj7CoMKgwqDCoMKgwqDC
oMKgwqAgc3RhdGljIHN0ZDo6c2hhcmVkX3B0ciZhbXA7bHQ7SUNsaWVudCZhbXA7Z3Q7IGJ1aWxk
Q2xpZW50KCkgezxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGF1dG8gY2xpZW50ID0gc3RkOjpz
aGFyZWRfcHRyKG5ldyBUQ2xpZW50KTs8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAuLi4gLy8g
SU1QT1JUQU5UIFRISU5HUyBBRlRFUiBJTklUSUFMSVpBVElPTi4gQ0FOTk9UIEJFIFNLSVBFRCAh
ITxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiBjbGllbnQ7PGJyPsKgwqDCoMKgwqDC
oMKgwqDCoCB9PGJyPsKgwqDCoMKgwqDCoMKgIHByb3RlY3RlZDo8YnI+wqDCoMKgwqDCoMKgwqDC
oMKgIENsaWVudCgpID0gZGVmYXVsdDs8YnI+wqDCoMKgwqDCoCB9Ozxicj48YnI+wqDCoMKgwqDC
oCB0ZW1wbGF0ZSAmYW1wO2x0O3R5cGVuYW1lIFQsIHR5cGVuYW1lIC4uLiBUQXJncyZhbXA7Z3Q7
PGJyPsKgwqDCoMKgwqAgc3RkOjpzaGFyZWRfcHRyJmFtcDtsdDtUJmFtcDtndDsgbWFrZV9zaGFy
ZWQoVEFyZ3MmYW1wOyZhbXA7Li4uIF9hcmdzKSB7PGJyPsKgwqDCoMKgwqDCoMKgIHJldHVybiBJ
Q2xpZW50OjpidWlsZENsaWVudChzdGQ6OmZvcndhcmQmYW1wO2x0O1RBcmdzJmFtcDtndDsoX2Fy
Z3MpLi4uKTs8YnI+wqDCoMKgwqDCoCB9PGJyPsKgwqDCoCB9wqAgLy8gbmFtZXNwYWNlIElQQ0J1
czxicj48YnI+wqDCoMKgIGNsYXNzIFJlYWxDbGllbnQgOiBwdWJsaWMgSUNsaWVudCB7PGJyPsKg
wqDCoMKgwqAgcHVibGljOjxicj7CoMKgwqDCoMKgwqAgUmVhbENsaWVudCgpPGJyPsKgwqDCoMKg
wqDCoMKgwqAgOiBJQ2xpZW50KCkgezxicj7CoMKgwqDCoMKgwqAgfTxicj7CoMKgwqAgfTs8YnI+
PGJyPsKgwqDCoCB1c2luZyBuYW1lc3BhY2Ugc3RkOzxicj48YnI+wqDCoMKgIGludCBtYWluKCkg
ezxicj7CoMKgwqDCoMKgIGF1dG8gcmVhbENsaWVudCA9IG1ha2Vfc2hhcmVkJmFtcDtsdDtSZWFs
Q2xpZW50JmFtcDtndDsoKTs8YnI+wqDCoMKgwqDCoCAvLyBXZSB1c2Ugb3VyIG93biB2ZXJzaW9u
IG9mIG1ha2Vfc2hhcmVkIHRoYXQgaXMgZGVsZWdhdGUgY3JlYXRpb24gb2Ygb2JqZWN0IHRvIGJ1
aWxkZXIgbWV0aG9kPGJyPsKgwqDCoMKgwqAgLy8gQ29vbCAhITxicj7CoMKgwqAgfTwvZGl2Pjxk
aXY+PGJyPjwvZGl2PjxkaXY+QXMgPGI+SGVyYiBTdXR0ZXI8L2I+IHNhaWQgYXQgPGI+Q3BwQ29u
IDIwMTc6IEhlcmIgU3V0dGVyIOKAnE1ldGE6IFRob3VnaHRzIG9uIGdlbmVyYXRpdmUgQysr4oCd
PC9iPjo8YnI+JnF1b3Q7QWJzdHJhY3Rpb24gYXJlIGhpZGVycyBieSBkZWZpbml0aW9uLiBJZiB0
aGV5IGRpZCBub3QgZG8gdGhpcyB0aGV5IGFyZSB1c2VsZXNzIC4uLiZxdW90Ozxicj4mcXVvdDtJ
dCYjMzk7cyBub3QgdGhlIHByb2JsZW0uIEl0IGlzIHRoZSBwb2ludC4mcXVvdDs8YnI+PGJyPkkg
c2VlIHRoaXMgc3VnZ2VzdGlvbiB0byBleHRlbmQgPGI+QURMPC9iPiBzZWFyY2ggb24gY2FsbGVy
IG9iamVjdCBhbmQgb24gdGVtcGxhdGUgcGFyYW1ldGVyIGFzIHNpbXBsaWZpZXIgZm9yIExpYnJh
cnkgV3JpdHRlcnMgYW5kIGFsc28gR2VuZXJhbCBQcm9ncmFtbWVyczxicj48L2Rpdj48L2Rpdj4N
Cg0KPHA+PC9wPgoKLS0gPGJyIC8+CllvdSByZWNlaXZlZCB0aGlzIG1lc3NhZ2UgYmVjYXVzZSB5
b3UgYXJlIHN1YnNjcmliZWQgdG8gdGhlIEdvb2dsZSBHcm91cHMgJnF1b3Q7SVNPIEMrKyBTdGFu
ZGFyZCAtIEZ1dHVyZSBQcm9wb3NhbHMmcXVvdDsgZ3JvdXAuPGJyIC8+ClRvIHVuc3Vic2NyaWJl
IGZyb20gdGhpcyBncm91cCBhbmQgc3RvcCByZWNlaXZpbmcgZW1haWxzIGZyb20gaXQsIHNlbmQg
YW4gZW1haWwgdG8gPGEgaHJlZj0ibWFpbHRvOnN0ZC1wcm9wb3NhbHMrdW5zdWJzY3JpYmVAaXNv
Y3BwLm9yZyI+c3RkLXByb3Bvc2Fscyt1bnN1YnNjcmliZUBpc29jcHAub3JnPC9hPi48YnIgLz4K
VG8gcG9zdCB0byB0aGlzIGdyb3VwLCBzZW5kIGVtYWlsIHRvIDxhIGhyZWY9Im1haWx0bzpzdGQt
cHJvcG9zYWxzQGlzb2NwcC5vcmciPnN0ZC1wcm9wb3NhbHNAaXNvY3BwLm9yZzwvYT4uPGJyIC8+
ClRvIHZpZXcgdGhpcyBkaXNjdXNzaW9uIG9uIHRoZSB3ZWIgdmlzaXQgPGEgaHJlZj0iaHR0cHM6
Ly9ncm91cHMuZ29vZ2xlLmNvbS9hL2lzb2NwcC5vcmcvZC9tc2dpZC9zdGQtcHJvcG9zYWxzLzc5
OWUxM2NiLTQzNTQtNGZmZS04NTY4LTI3NmUxY2JmZTYxYyU0MGlzb2NwcC5vcmc/dXRtX21lZGl1
bT1lbWFpbCZ1dG1fc291cmNlPWZvb3RlciI+aHR0cHM6Ly9ncm91cHMuZ29vZ2xlLmNvbS9hL2lz
b2NwcC5vcmcvZC9tc2dpZC9zdGQtcHJvcG9zYWxzLzc5OWUxM2NiLTQzNTQtNGZmZS04NTY4LTI3
NmUxY2JmZTYxYyU0MGlzb2NwcC5vcmc8L2E+LjxiciAvPgo=
------=_Part_2222_644902254.1539108673494--

------=_Part_2221_237128896.1539108673494--

.


Author: Denis Kotov <redradist@gmail.com>
Date: Tue, 9 Oct 2018 11:16:50 -0700 (PDT)
Raw View
------=_Part_2502_862610117.1539109010862
Content-Type: multipart/alternative;
 boundary="----=_Part_2503_625164551.1539109010863"

------=_Part_2503_625164551.1539109010863
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

This proposal is available on GitHub also=20
https://github.com/redradist/cpp_standard_propousals/blob/master/ADL%20Exte=
nsion.html=20

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 9 =D0=BE=D0=BA=D1=82=D1=8F=D0=
=B1=D1=80=D1=8F 2018 =D0=B3., 21:11:13 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=
=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Denis Kotov =D0=BD=D0=B0=D0=BF=
=D0=B8=D1=81=D0=B0=D0=BB:
>
> Hello everyone,
>
> I have prepared the proposal for extending an ADL search algorithm:
>
> *Propousal for extension methods like.* Lets consider the following=20
> example:
>
>     namespace DeviceManager {
>       class Device {
>         public:
>           ... // Other member functions
>           uint32_t getId() const {
>             return id_;
>           }
>         private:
>           ... // Other member variables
>           uint32_t id_;
>       };
>
>       using DeviceList =3D std::vector&lt;Device&gt;;
>
>       Device mergeDeviceInfo(const Device & _first, const Device &=20
> _second) {
>         ... // Implementation
>       }
>     }
>
>     int main() {
>       DeviceManager::DeviceList deviceList;
>       ... // Some work
>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),=20
> deviceList.end(), [=3D] {
>         ... // Some first creteria
>       });
>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),=20
> deviceList.end(), [=3D] {
>         ... // Some second creteria
>       });
>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=3D=
=20
> foundDeviceIter1) {
>         DeviceManager::Device mergedDevice =3D=20
> DeviceManager::mergeDeviceInfo(*foundDeviceIter0, *foundDeviceIter1);
>         ... // Some other work
>       }
>     }
>
> As you can see in case one helper function it is easy to manipulate and=
=20
> use it, but in case of a lot of functions it would be better to support=
=20
> some kind of extension methods:
>
> namespace DeviceManager {
>       class Device {
>         public:
>           ... // Other member functions
>           uint32_t getId() const {
>             return id_;
>           }
>         private:
>           ... // Other member variables
>           uint32_t id_;
>       };
>
>       using DeviceList =3D std::vector&lt;Device&gt;;
>
>       // 1. If it is called by reference type prefer this overload functi=
on
>       Device mergeDeviceInfo(const Device & _first, const Device &=20
> _second) {
>         ... // Implementation
>       }
>       // 2. If it is called by pointer type prefer this overload function
>       Device mergeDeviceInfo(const Device * _firstPtr, const Device *=20
> _secondPtr) {
>         ... // Implementation
>       }
>     }
>
>     int main() {
>       DeviceManager::DeviceList deviceList;
>       ... // Some work
>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),=20
> deviceList.end(), [=3D] {
>         ... // Some first creteria
>       });
>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),=20
> deviceList.end(), [=3D] {
>         ... // Some second creteria
>       });
>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=3D=
=20
> foundDeviceIter1) {
>         // 1. Overload function for references if called
>         // ADL will search in dependent scopes also for calling functions=
=20
> by object reference
>         DeviceManager::Device & firstFoundDevice =3D *foundDeviceIter0;
>         DeviceManager::Device & secondFoundDevice =3D *foundDeviceIter1;
>         DeviceManager::Device mergedDevice =3D=20
> firstFoundDevice.mergeDeviceInfo(secondFoundDevice);
>
>         // 2. Overload function for pointers if called
>         // ADL will search in dependent scopes lso for calling functions=
=20
> by object pointer
>         DeviceManager::Device mergedDevice =3D=20
> foundDeviceIter0->mergeDeviceInfo(*foundDeviceIter1);
>         ... // Some other work
>       }
>     }
>
> *Propousal for extension of ADL on template parameter.* Lets consider the=
=20
> following example:
>
>     namespace IPCBus {
>       class IClient {
>         public:
>           ... // Other member functions
>           template &lt;typename TClient&gt;
>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>             auto client =3D std::shared_ptr(new TClient);
>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE SKIPE=
D=20
> !!
>             return client;
>           }
>         protected:
>           Client() =3D default;
>       };
>     }  // namespace IPCBus
>
>     class RealClient : public IClient {
>       public:
>        RealClient()
>          : IClient() {
>        }
>     };
>
>     using namespace std;
>
>     int main() {
>       auto realClient =3D make_shared&lt;RealClient&gt;();
>       // WE MISSED THE VERY IMPORTANT STEPS IN CREATION OF OBJECT !!
>     }
>
> As you can see in case one helper function it is easy to manipulate and=
=20
> use it, but in case of a lot of functions it would be better to support=
=20
> some kind of extension methods:
>
>     namespace IPCBus {
>       class IClient {
>         public:
>           ... // Other member functions
>           template &lt;typename TClient&gt;
>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>             auto client =3D std::shared_ptr(new TClient);
>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE SKIPE=
D=20
> !!
>             return client;
>           }
>         protected:
>           Client() =3D default;
>       };
>
>       template &lt;typename T, typename ... TArgs&gt;
>       std::shared_ptr&lt;T&gt; make_shared(TArgs&&... _args) {
>         return IClient::buildClient(std::forward&lt;TArgs&gt;(_args)...);
>       }
>     }  // namespace IPCBus
>
>     class RealClient : public IClient {
>       public:
>        RealClient()
>          : IClient() {
>        }
>     };
>
>     using namespace std;
>
>     int main() {
>       auto realClient =3D make_shared&lt;RealClient&gt;();
>       // We use our own version of make_shared that is delegate creation=
=20
> of object to builder method
>       // Cool !!
>     }
>
> As *Herb Sutter* said at *CppCon 2017: Herb Sutter =E2=80=9CMeta: Thought=
s on=20
> generative C++=E2=80=9D*:
> "Abstraction are hiders by definition. If they did not do this they are=
=20
> useless ..."
> "It's not the problem. It is the point."
>
> I see this suggestion to extend *ADL* search on caller object and on=20
> template parameter as simplifier for Library Writters and also General=20
> Programmers
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/cf51a959-42d4-42c5-9e25-1455681402ff%40isocpp.or=
g.

------=_Part_2503_625164551.1539109010863
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: base64

PGRpdiBkaXI9Imx0ciI+VGhpcyBwcm9wb3NhbCBpcyBhdmFpbGFibGUgb24gR2l0SHViIGFsc28g
PGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3JlZHJhZGlzdC9jcHBfc3RhbmRhcmRfcHJvcG91
c2Fscy9ibG9iL21hc3Rlci9BREwlMjBFeHRlbnNpb24uaHRtbCI+aHR0cHM6Ly9naXRodWIuY29t
L3JlZHJhZGlzdC9jcHBfc3RhbmRhcmRfcHJvcG91c2Fscy9ibG9iL21hc3Rlci9BREwlMjBFeHRl
bnNpb24uaHRtbDwvYT4gPGJyPjxicj7QstGC0L7RgNC90LjQuiwgOSDQvtC60YLRj9Cx0YDRjyAy
MDE4INCzLiwgMjE6MTE6MTMgVVRDKzMg0L/QvtC70YzQt9C+0LLQsNGC0LXQu9GMIERlbmlzIEtv
dG92INC90LDQv9C40YHQsNC7OjxibG9ja3F1b3RlIGNsYXNzPSJnbWFpbF9xdW90ZSIgc3R5bGU9
Im1hcmdpbjogMDttYXJnaW4tbGVmdDogMC44ZXg7Ym9yZGVyLWxlZnQ6IDFweCAjY2NjIHNvbGlk
O3BhZGRpbmctbGVmdDogMWV4OyI+PGRpdiBkaXI9Imx0ciI+PGRpdj5IZWxsbyBldmVyeW9uZSw8
L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkkgaGF2ZSBwcmVwYXJlZCB0aGUgcHJvcG9zYWwgZm9y
IGV4dGVuZGluZyBhbiBBREwgc2VhcmNoIGFsZ29yaXRobTo8L2Rpdj48ZGl2Pjxicj48L2Rpdj48
ZGl2PjxiPlByb3BvdXNhbCBmb3IgZXh0ZW5zaW9uIG1ldGhvZHMgbGlrZS48L2I+IExldHMgY29u
c2lkZXIgdGhlIGZvbGxvd2luZyBleGFtcGxlOjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+wqDC
oMKgIG5hbWVzcGFjZSBEZXZpY2VNYW5hZ2VyIHs8YnI+wqDCoMKgwqDCoCBjbGFzcyBEZXZpY2Ug
ezxicj7CoMKgwqDCoMKgwqDCoCBwdWJsaWM6PGJyPsKgwqDCoMKgwqDCoMKgwqDCoCAuLi4gLy8g
T3RoZXIgbWVtYmVyIGZ1bmN0aW9uczxicj7CoMKgwqDCoMKgwqDCoMKgwqAgdWludDMyX3QgZ2V0
SWQoKSBjb25zdCB7PGJyPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIGlkXzs8YnI+wqDC
oMKgwqDCoMKgwqDCoMKgIH08YnI+wqDCoMKgwqDCoMKgwqAgcHJpdmF0ZTo8YnI+wqDCoMKgwqDC
oMKgwqDCoMKgIC4uLiAvLyBPdGhlciBtZW1iZXIgdmFyaWFibGVzPGJyPsKgwqDCoMKgwqDCoMKg
wqDCoCB1aW50MzJfdCBpZF87PGJyPsKgwqDCoMKgwqAgfTs8YnI+PGJyPsKgwqDCoMKgwqAgdXNp
bmcgRGV2aWNlTGlzdCA9IHN0ZDo6dmVjdG9yJmFtcDtsdDtEZXZpY2UmYW1wO2d0Ozs8YnI+PGJy
PsKgwqDCoMKgwqAgRGV2aWNlIG1lcmdlRGV2aWNlSW5mbyhjb25zdCBEZXZpY2UgJmFtcDsgX2Zp
cnN0LCBjb25zdCBEZXZpY2UgJmFtcDsgX3NlY29uZCkgezxicj7CoMKgwqDCoMKgwqDCoCAuLi4g
Ly8gSW1wbGVtZW50YXRpb248YnI+wqDCoMKgwqDCoCB9PGJyPsKgwqDCoCB9PGJyPjxicj7CoMKg
wqAgaW50IG1haW4oKSB7PGJyPsKgwqDCoMKgwqAgRGV2aWNlTWFuYWdlcjo6RGV2aWNlTGlzdCBk
ZXZpY2VMaXN0Ozxicj7CoMKgwqDCoMKgIC4uLiAvLyBTb21lIHdvcms8YnI+wqDCoMKgwqDCoCBh
dXRvIGZvdW5kRGV2aWNlSXRlcjAgPSBzdGQ6OmZpbmRfaWYoZGV2aWNlTGlzdC5iZWdpbig8d2Jy
PiksIGRldmljZUxpc3QuZW5kKCksIFs9XSB7PGJyPsKgwqDCoMKgwqDCoMKgIC4uLiAvLyBTb21l
IGZpcnN0IGNyZXRlcmlhPGJyPsKgwqDCoMKgwqAgfSk7PGJyPsKgwqDCoMKgwqAgYXV0byBmb3Vu
ZERldmljZUl0ZXIxID0gc3RkOjpmaW5kX2lmKGRldmljZUxpc3QuYmVnaW4oPHdicj4pLCBkZXZp
Y2VMaXN0LmVuZCgpLCBbPV0gezxicj7CoMKgwqDCoMKgwqDCoCAuLi4gLy8gU29tZSBzZWNvbmQg
Y3JldGVyaWE8YnI+wqDCoMKgwqDCoCB9KTs8YnI+wqDCoMKgwqDCoCBpZiAoZGV2aWNlTGlzdC5l
bmQoKSAhPSBmb3VuZERldmljZUl0ZXIwICZhbXA7JmFtcDsgZGV2aWNlTGlzdC5lbmQoKSAhPSBm
b3VuZERldmljZUl0ZXIxKSB7PGJyPsKgwqDCoMKgwqDCoMKgIERldmljZU1hbmFnZXI6OkRldmlj
ZSBtZXJnZWREZXZpY2UgPSBEZXZpY2VNYW5hZ2VyOjo8d2JyPm1lcmdlRGV2aWNlSW5mbygqPHdi
cj5mb3VuZERldmljZUl0ZXIwLCAqZm91bmREZXZpY2VJdGVyMSk7PGJyPsKgwqDCoMKgwqDCoMKg
IC4uLiAvLyBTb21lIG90aGVyIHdvcms8YnI+wqDCoMKgwqDCoCB9PGJyPsKgwqDCoCB9PC9kaXY+
PGRpdj48YnI+PC9kaXY+PGRpdj5BcyB5b3UgY2FuIHNlZSBpbiBjYXNlIG9uZSBoZWxwZXIgZnVu
Y3Rpb24gaXQgaXMgZWFzeSB0byBtYW5pcHVsYXRlIGFuZCB1c2UgaXQsIGJ1dCBpbiBjYXNlIG9m
IGEgbG90IG9mIGZ1bmN0aW9ucyBpdCB3b3VsZCBiZSBiZXR0ZXIgdG8gc3VwcG9ydCBzb21lIGtp
bmQgb2YgZXh0ZW5zaW9uIG1ldGhvZHM6PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5uYW1lc3Bh
Y2UgRGV2aWNlTWFuYWdlciB7PGJyPsKgwqDCoMKgwqAgY2xhc3MgRGV2aWNlIHs8YnI+wqDCoMKg
wqDCoMKgwqAgcHVibGljOjxicj7CoMKgwqDCoMKgwqDCoMKgwqAgLi4uIC8vIE90aGVyIG1lbWJl
ciBmdW5jdGlvbnM8YnI+wqDCoMKgwqDCoMKgwqDCoMKgIHVpbnQzMl90IGdldElkKCkgY29uc3Qg
ezxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiBpZF87PGJyPsKgwqDCoMKgwqDCoMKg
wqDCoCB9PGJyPsKgwqDCoMKgwqDCoMKgIHByaXZhdGU6PGJyPsKgwqDCoMKgwqDCoMKgwqDCoCAu
Li4gLy8gT3RoZXIgbWVtYmVyIHZhcmlhYmxlczxicj7CoMKgwqDCoMKgwqDCoMKgwqAgdWludDMy
X3QgaWRfOzxicj7CoMKgwqDCoMKgIH07PGJyPjxicj7CoMKgwqDCoMKgIHVzaW5nIERldmljZUxp
c3QgPSBzdGQ6OnZlY3RvciZhbXA7bHQ7RGV2aWNlJmFtcDtndDs7PGJyPjxicj7CoMKgwqDCoMKg
IC8vIDEuIElmIGl0IGlzIGNhbGxlZCBieSByZWZlcmVuY2UgdHlwZSBwcmVmZXIgdGhpcyBvdmVy
bG9hZCBmdW5jdGlvbjxicj7CoMKgwqDCoMKgIERldmljZSBtZXJnZURldmljZUluZm8oY29uc3Qg
RGV2aWNlICZhbXA7IF9maXJzdCwgY29uc3QgRGV2aWNlICZhbXA7IF9zZWNvbmQpIHs8YnI+wqDC
oMKgwqDCoMKgwqAgLi4uIC8vIEltcGxlbWVudGF0aW9uPGJyPsKgwqDCoMKgwqAgfTxicj7CoMKg
wqDCoMKgIC8vIDIuIElmIGl0IGlzIGNhbGxlZCBieSBwb2ludGVyIHR5cGUgcHJlZmVyIHRoaXMg
b3ZlcmxvYWQgZnVuY3Rpb248YnI+wqDCoMKgwqDCoCBEZXZpY2UgbWVyZ2VEZXZpY2VJbmZvKGNv
bnN0IERldmljZSAqIF9maXJzdFB0ciwgY29uc3QgRGV2aWNlICogX3NlY29uZFB0cikgezxicj7C
oMKgwqDCoMKgwqDCoCAuLi4gLy8gSW1wbGVtZW50YXRpb248YnI+wqDCoMKgwqDCoCB9PGJyPsKg
wqDCoCB9PGJyPjxicj7CoMKgwqAgaW50IG1haW4oKSB7PGJyPsKgwqDCoMKgwqAgRGV2aWNlTWFu
YWdlcjo6RGV2aWNlTGlzdCBkZXZpY2VMaXN0Ozxicj7CoMKgwqDCoMKgIC4uLiAvLyBTb21lIHdv
cms8YnI+wqDCoMKgwqDCoCBhdXRvIGZvdW5kRGV2aWNlSXRlcjAgPSBzdGQ6OmZpbmRfaWYoZGV2
aWNlTGlzdC5iZWdpbig8d2JyPiksIGRldmljZUxpc3QuZW5kKCksIFs9XSB7PGJyPsKgwqDCoMKg
wqDCoMKgIC4uLiAvLyBTb21lIGZpcnN0IGNyZXRlcmlhPGJyPsKgwqDCoMKgwqAgfSk7PGJyPsKg
wqDCoMKgwqAgYXV0byBmb3VuZERldmljZUl0ZXIxID0gc3RkOjpmaW5kX2lmKGRldmljZUxpc3Qu
YmVnaW4oPHdicj4pLCBkZXZpY2VMaXN0LmVuZCgpLCBbPV0gezxicj7CoMKgwqDCoMKgwqDCoCAu
Li4gLy8gU29tZSBzZWNvbmQgY3JldGVyaWE8YnI+wqDCoMKgwqDCoCB9KTs8YnI+wqDCoMKgwqDC
oCBpZiAoZGV2aWNlTGlzdC5lbmQoKSAhPSBmb3VuZERldmljZUl0ZXIwICZhbXA7JmFtcDsgZGV2
aWNlTGlzdC5lbmQoKSAhPSBmb3VuZERldmljZUl0ZXIxKSB7PGJyPsKgwqDCoMKgwqDCoMKgIC8v
IDEuIE92ZXJsb2FkIGZ1bmN0aW9uIGZvciByZWZlcmVuY2VzIGlmIGNhbGxlZDxicj7CoMKgwqDC
oMKgwqDCoCAvLyBBREwgd2lsbCBzZWFyY2ggaW4gZGVwZW5kZW50IHNjb3BlcyBhbHNvIGZvciBj
YWxsaW5nIGZ1bmN0aW9ucyBieSBvYmplY3QgcmVmZXJlbmNlPGJyPsKgwqDCoMKgwqDCoMKgIERl
dmljZU1hbmFnZXI6OkRldmljZSAmYW1wOyBmaXJzdEZvdW5kRGV2aWNlID0gKmZvdW5kRGV2aWNl
SXRlcjA7PGJyPsKgwqDCoMKgwqDCoMKgIERldmljZU1hbmFnZXI6OkRldmljZSAmYW1wOyBzZWNv
bmRGb3VuZERldmljZSA9ICpmb3VuZERldmljZUl0ZXIxOzxicj7CoMKgwqDCoMKgwqDCoCBEZXZp
Y2VNYW5hZ2VyOjpEZXZpY2UgbWVyZ2VkRGV2aWNlID0gZmlyc3RGb3VuZERldmljZS48d2JyPm1l
cmdlRGV2aWNlSW5mbyg8d2JyPnNlY29uZEZvdW5kRGV2aWNlKTs8YnI+PGJyPsKgwqDCoMKgwqDC
oMKgIC8vIDIuIE92ZXJsb2FkIGZ1bmN0aW9uIGZvciBwb2ludGVycyBpZiBjYWxsZWQ8YnI+wqDC
oMKgwqDCoMKgwqAgLy8gQURMIHdpbGwgc2VhcmNoIGluIGRlcGVuZGVudCBzY29wZXMgbHNvIGZv
ciBjYWxsaW5nIGZ1bmN0aW9ucyBieSBvYmplY3QgcG9pbnRlcjxicj7CoMKgwqDCoMKgwqDCoCBE
ZXZpY2VNYW5hZ2VyOjpEZXZpY2UgbWVyZ2VkRGV2aWNlID0gZm91bmREZXZpY2VJdGVyMC0mZ3Q7
PHdicj5tZXJnZURldmljZUluZm8oKjx3YnI+Zm91bmREZXZpY2VJdGVyMSk7PGJyPsKgwqDCoMKg
wqDCoMKgIC4uLiAvLyBTb21lIG90aGVyIHdvcms8YnI+wqDCoMKgwqDCoCB9PGJyPsKgwqDCoCB9
PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj48Yj5Qcm9wb3VzYWwgZm9yIGV4dGVuc2lvbiBvZiBB
REwgb24gdGVtcGxhdGUgcGFyYW1ldGVyLjwvYj4gTGV0cyBjb25zaWRlciB0aGUgZm9sbG93aW5n
IGV4YW1wbGU6PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj7CoMKgwqAgbmFtZXNwYWNlIElQQ0J1
cyB7PGJyPsKgwqDCoMKgwqAgY2xhc3MgSUNsaWVudCB7PGJyPsKgwqDCoMKgwqDCoMKgIHB1Ymxp
Yzo8YnI+wqDCoMKgwqDCoMKgwqDCoMKgIC4uLiAvLyBPdGhlciBtZW1iZXIgZnVuY3Rpb25zPGJy
PsKgwqDCoMKgwqDCoMKgwqDCoCB0ZW1wbGF0ZSAmYW1wO2x0O3R5cGVuYW1lIFRDbGllbnQmYW1w
O2d0Ozxicj7CoMKgwqDCoMKgwqDCoMKgwqAgc3RhdGljIHN0ZDo6c2hhcmVkX3B0ciZhbXA7bHQ7
SUNsaWVudCZhbXA7Z3Q7IGJ1aWxkQ2xpZW50KCkgezxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKg
IGF1dG8gY2xpZW50ID0gc3RkOjpzaGFyZWRfcHRyKG5ldyBUQ2xpZW50KTs8YnI+wqDCoMKgwqDC
oMKgwqDCoMKgwqDCoCAuLi4gLy8gSU1QT1JUQU5UIFRISU5HUyBBRlRFUiBJTklUSUFMSVpBVElP
Ti4gQ0FOTk9UIEJFIFNLSVBFRCAhITxicj7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiBj
bGllbnQ7PGJyPsKgwqDCoMKgwqDCoMKgwqDCoCB9PGJyPsKgwqDCoMKgwqDCoMKgIHByb3RlY3Rl
ZDo8YnI+wqDCoMKgwqDCoMKgwqDCoMKgIENsaWVudCgpID0gZGVmYXVsdDs8YnI+wqDCoMKgwqDC
oCB9Ozxicj7CoMKgwqAgfcKgIC8vIG5hbWVzcGFjZSBJUENCdXM8YnI+PGJyPsKgwqDCoCBjbGFz
cyBSZWFsQ2xpZW50IDogcHVibGljIElDbGllbnQgezxicj7CoMKgwqDCoMKgIHB1YmxpYzo8YnI+
wqDCoMKgwqDCoMKgIFJlYWxDbGllbnQoKTxicj7CoMKgwqDCoMKgwqDCoMKgIDogSUNsaWVudCgp
IHs8YnI+wqDCoMKgwqDCoMKgIH08YnI+wqDCoMKgIH07PGJyPjxicj7CoMKgwqAgdXNpbmcgbmFt
ZXNwYWNlIHN0ZDs8YnI+PGJyPsKgwqDCoCBpbnQgbWFpbigpIHs8YnI+wqDCoMKgwqDCoCBhdXRv
IHJlYWxDbGllbnQgPSBtYWtlX3NoYXJlZCZhbXA7bHQ7UmVhbENsaWVudCZhbXA7Z3Q7KDx3YnI+
KTs8YnI+wqDCoMKgwqDCoCAvLyBXRSBNSVNTRUQgVEhFIFZFUlkgSU1QT1JUQU5UIFNURVBTIElO
IENSRUFUSU9OIE9GIE9CSkVDVCAhITxicj7CoMKgwqAgfTwvZGl2PjxkaXY+PGJyPjwvZGl2Pjxk
aXY+QXMgeW91IGNhbiBzZWUgaW4gY2FzZSBvbmUgaGVscGVyIGZ1bmN0aW9uIGl0IGlzIGVhc3kg
dG8gbWFuaXB1bGF0ZSBhbmQgdXNlIGl0LCBidXQgaW4gY2FzZSBvZiBhIGxvdCBvZiBmdW5jdGlv
bnMgaXQgd291bGQgYmUgYmV0dGVyIHRvIHN1cHBvcnQgc29tZSBraW5kIG9mIGV4dGVuc2lvbiBt
ZXRob2RzOjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+wqDCoMKgIG5hbWVzcGFjZSBJUENCdXMg
ezxicj7CoMKgwqDCoMKgIGNsYXNzIElDbGllbnQgezxicj7CoMKgwqDCoMKgwqDCoCBwdWJsaWM6
PGJyPsKgwqDCoMKgwqDCoMKgwqDCoCAuLi4gLy8gT3RoZXIgbWVtYmVyIGZ1bmN0aW9uczxicj7C
oMKgwqDCoMKgwqDCoMKgwqAgdGVtcGxhdGUgJmFtcDtsdDt0eXBlbmFtZSBUQ2xpZW50JmFtcDtn
dDs8YnI+wqDCoMKgwqDCoMKgwqDCoMKgIHN0YXRpYyBzdGQ6OnNoYXJlZF9wdHImYW1wO2x0O0lD
bGllbnQmYW1wO2d0OyBidWlsZENsaWVudCgpIHs8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBh
dXRvIGNsaWVudCA9IHN0ZDo6c2hhcmVkX3B0cihuZXcgVENsaWVudCk7PGJyPsKgwqDCoMKgwqDC
oMKgwqDCoMKgwqAgLi4uIC8vIElNUE9SVEFOVCBUSElOR1MgQUZURVIgSU5JVElBTElaQVRJT04u
IENBTk5PVCBCRSBTS0lQRUQgISE8YnI+wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gY2xp
ZW50Ozxicj7CoMKgwqDCoMKgwqDCoMKgwqAgfTxicj7CoMKgwqDCoMKgwqDCoCBwcm90ZWN0ZWQ6
PGJyPsKgwqDCoMKgwqDCoMKgwqDCoCBDbGllbnQoKSA9IGRlZmF1bHQ7PGJyPsKgwqDCoMKgwqAg
fTs8YnI+PGJyPsKgwqDCoMKgwqAgdGVtcGxhdGUgJmFtcDtsdDt0eXBlbmFtZSBULCB0eXBlbmFt
ZSAuLi4gVEFyZ3MmYW1wO2d0Ozxicj7CoMKgwqDCoMKgIHN0ZDo6c2hhcmVkX3B0ciZhbXA7bHQ7
VCZhbXA7Z3Q7IG1ha2Vfc2hhcmVkKFRBcmdzJmFtcDsmYW1wOy4uLiBfYXJncykgezxicj7CoMKg
wqDCoMKgwqDCoCByZXR1cm4gSUNsaWVudDo6YnVpbGRDbGllbnQoc3RkOjo8d2JyPmZvcndhcmQm
YW1wO2x0O1RBcmdzJmFtcDtndDsoX2FyZ3MpLi4uPHdicj4pOzxicj7CoMKgwqDCoMKgIH08YnI+
wqDCoMKgIH3CoCAvLyBuYW1lc3BhY2UgSVBDQnVzPGJyPjxicj7CoMKgwqAgY2xhc3MgUmVhbENs
aWVudCA6IHB1YmxpYyBJQ2xpZW50IHs8YnI+wqDCoMKgwqDCoCBwdWJsaWM6PGJyPsKgwqDCoMKg
wqDCoCBSZWFsQ2xpZW50KCk8YnI+wqDCoMKgwqDCoMKgwqDCoCA6IElDbGllbnQoKSB7PGJyPsKg
wqDCoMKgwqDCoCB9PGJyPsKgwqDCoCB9Ozxicj48YnI+wqDCoMKgIHVzaW5nIG5hbWVzcGFjZSBz
dGQ7PGJyPjxicj7CoMKgwqAgaW50IG1haW4oKSB7PGJyPsKgwqDCoMKgwqAgYXV0byByZWFsQ2xp
ZW50ID0gbWFrZV9zaGFyZWQmYW1wO2x0O1JlYWxDbGllbnQmYW1wO2d0Oyg8d2JyPik7PGJyPsKg
wqDCoMKgwqAgLy8gV2UgdXNlIG91ciBvd24gdmVyc2lvbiBvZiBtYWtlX3NoYXJlZCB0aGF0IGlz
IGRlbGVnYXRlIGNyZWF0aW9uIG9mIG9iamVjdCB0byBidWlsZGVyIG1ldGhvZDxicj7CoMKgwqDC
oMKgIC8vIENvb2wgISE8YnI+wqDCoMKgIH08L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkFzIDxi
PkhlcmIgU3V0dGVyPC9iPiBzYWlkIGF0IDxiPkNwcENvbiAyMDE3OiBIZXJiIFN1dHRlciDigJxN
ZXRhOiBUaG91Z2h0cyBvbiBnZW5lcmF0aXZlIEMrK+KAnTwvYj46PGJyPiZxdW90O0Fic3RyYWN0
aW9uIGFyZSBoaWRlcnMgYnkgZGVmaW5pdGlvbi4gSWYgdGhleSBkaWQgbm90IGRvIHRoaXMgdGhl
eSBhcmUgdXNlbGVzcyAuLi4mcXVvdDs8YnI+JnF1b3Q7SXQmIzM5O3Mgbm90IHRoZSBwcm9ibGVt
LiBJdCBpcyB0aGUgcG9pbnQuJnF1b3Q7PGJyPjxicj5JIHNlZSB0aGlzIHN1Z2dlc3Rpb24gdG8g
ZXh0ZW5kIDxiPkFETDwvYj4gc2VhcmNoIG9uIGNhbGxlciBvYmplY3QgYW5kIG9uIHRlbXBsYXRl
IHBhcmFtZXRlciBhcyBzaW1wbGlmaWVyIGZvciBMaWJyYXJ5IFdyaXR0ZXJzIGFuZCBhbHNvIEdl
bmVyYWwgUHJvZ3JhbW1lcnM8YnI+PC9kaXY+PC9kaXY+PC9ibG9ja3F1b3RlPjwvZGl2Pg0KDQo8
cD48L3A+CgotLSA8YnIgLz4KWW91IHJlY2VpdmVkIHRoaXMgbWVzc2FnZSBiZWNhdXNlIHlvdSBh
cmUgc3Vic2NyaWJlZCB0byB0aGUgR29vZ2xlIEdyb3VwcyAmcXVvdDtJU08gQysrIFN0YW5kYXJk
IC0gRnV0dXJlIFByb3Bvc2FscyZxdW90OyBncm91cC48YnIgLz4KVG8gdW5zdWJzY3JpYmUgZnJv
bSB0aGlzIGdyb3VwIGFuZCBzdG9wIHJlY2VpdmluZyBlbWFpbHMgZnJvbSBpdCwgc2VuZCBhbiBl
bWFpbCB0byA8YSBocmVmPSJtYWlsdG86c3RkLXByb3Bvc2Fscyt1bnN1YnNjcmliZUBpc29jcHAu
b3JnIj5zdGQtcHJvcG9zYWxzK3Vuc3Vic2NyaWJlQGlzb2NwcC5vcmc8L2E+LjxiciAvPgpUbyBw
b3N0IHRvIHRoaXMgZ3JvdXAsIHNlbmQgZW1haWwgdG8gPGEgaHJlZj0ibWFpbHRvOnN0ZC1wcm9w
b3NhbHNAaXNvY3BwLm9yZyI+c3RkLXByb3Bvc2Fsc0Bpc29jcHAub3JnPC9hPi48YnIgLz4KVG8g
dmlldyB0aGlzIGRpc2N1c3Npb24gb24gdGhlIHdlYiB2aXNpdCA8YSBocmVmPSJodHRwczovL2dy
b3Vwcy5nb29nbGUuY29tL2EvaXNvY3BwLm9yZy9kL21zZ2lkL3N0ZC1wcm9wb3NhbHMvY2Y1MWE5
NTktNDJkNC00MmM1LTllMjUtMTQ1NTY4MTQwMmZmJTQwaXNvY3BwLm9yZz91dG1fbWVkaXVtPWVt
YWlsJnV0bV9zb3VyY2U9Zm9vdGVyIj5odHRwczovL2dyb3Vwcy5nb29nbGUuY29tL2EvaXNvY3Bw
Lm9yZy9kL21zZ2lkL3N0ZC1wcm9wb3NhbHMvY2Y1MWE5NTktNDJkNC00MmM1LTllMjUtMTQ1NTY4
MTQwMmZmJTQwaXNvY3BwLm9yZzwvYT4uPGJyIC8+Cg==
------=_Part_2503_625164551.1539109010863--

------=_Part_2502_862610117.1539109010862--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Tue, 9 Oct 2018 13:28:24 -0700
Raw View
--0000000000000d22c60577d1952d
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Tue, 9 Oct 2018 at 11:11, Denis Kotov <redradist@gmail.com> wrote:

> Hello everyone,
>
> I have prepared the proposal for extending an ADL search algorithm:
>
> *Propousal for extension methods like.* Lets consider the following
> example:
>
>     namespace DeviceManager {
>       class Device {
>         public:
>           ... // Other member functions
>           uint32_t getId() const {
>             return id_;
>           }
>         private:
>           ... // Other member variables
>           uint32_t id_;
>       };
>
>       using DeviceList =3D std::vector&lt;Device&gt;;
>
>       Device mergeDeviceInfo(const Device & _first, const Device &
> _second) {
>         ... // Implementation
>       }
>     }
>
>     int main() {
>       DeviceManager::DeviceList deviceList;
>       ... // Some work
>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),
> deviceList.end(), [=3D] {
>         ... // Some first creteria
>       });
>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),
> deviceList.end(), [=3D] {
>         ... // Some second creteria
>       });
>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=3D
> foundDeviceIter1) {
>         DeviceManager::Device mergedDevice =3D
> DeviceManager::mergeDeviceInfo(*foundDeviceIter0, *foundDeviceIter1);
>         ... // Some other work
>       }
>     }
>
> As you can see in case one helper function it is easy to manipulate and
> use it, but in case of a lot of functions it would be better to support
> some kind of extension methods:
>
> namespace DeviceManager {
>       class Device {
>         public:
>           ... // Other member functions
>           uint32_t getId() const {
>             return id_;
>           }
>         private:
>           ... // Other member variables
>           uint32_t id_;
>       };
>
>       using DeviceList =3D std::vector&lt;Device&gt;;
>
>       // 1. If it is called by reference type prefer this overload functi=
on
>       Device mergeDeviceInfo(const Device & _first, const Device &
> _second) {
>         ... // Implementation
>       }
>       // 2. If it is called by pointer type prefer this overload function
>       Device mergeDeviceInfo(const Device * _firstPtr, const Device *
> _secondPtr) {
>         ... // Implementation
>       }
>     }
>
>     int main() {
>       DeviceManager::DeviceList deviceList;
>       ... // Some work
>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),
> deviceList.end(), [=3D] {
>         ... // Some first creteria
>       });
>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),
> deviceList.end(), [=3D] {
>         ... // Some second creteria
>       });
>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=3D
> foundDeviceIter1) {
>         // 1. Overload function for references if called
>         // ADL will search in dependent scopes also for calling functions
> by object reference
>         DeviceManager::Device & firstFoundDevice =3D *foundDeviceIter0;
>         DeviceManager::Device & secondFoundDevice =3D *foundDeviceIter1;
>         DeviceManager::Device mergedDevice =3D
> firstFoundDevice.mergeDeviceInfo(secondFoundDevice);
>
>         // 2. Overload function for pointers if called
>         // ADL will search in dependent scopes lso for calling functions
> by object pointer
>         DeviceManager::Device mergedDevice =3D
> foundDeviceIter0->mergeDeviceInfo(*foundDeviceIter1);
>         ... // Some other work
>       }
>     }
>
> *Propousal for extension of ADL on template parameter.* Lets consider the
> following example:
>
>     namespace IPCBus {
>       class IClient {
>         public:
>           ... // Other member functions
>           template &lt;typename TClient&gt;
>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>             auto client =3D std::shared_ptr(new TClient);
>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE SKIPE=
D
> !!
>             return client;
>           }
>         protected:
>           Client() =3D default;
>       };
>     }  // namespace IPCBus
>
>     class RealClient : public IClient {
>       public:
>        RealClient()
>          : IClient() {
>        }
>     };
>
>     using namespace std;
>
>     int main() {
>       auto realClient =3D make_shared&lt;RealClient&gt;();
>       // WE MISSED THE VERY IMPORTANT STEPS IN CREATION OF OBJECT !!
>

If you don't want RealClient instances to be created by calling the default
constructor, the default constructor should not be public. There are other
techniques you can use to allow IClient to create instances of RealClient
without exposing a public default constructor that creates a broken object.
Your approach doesn't stop someone from doing this:

  make_unique<RealClient>() // still broken

or this:

  std::make_shared<RealClient>() // still broken

It's also broken by the intent of P0551R3 (adopted for C++20), which
intends to make it possible to implement standard library functions as
function objects instead of as real functions, and by P0921R2, which says
that you can't rely on (for instance) how a standard-library function will
partially order with respect to a function of your own.

So I don't think this approach really solves the problem you're trying to
address, especially not when used to subvert calls to standard library
functions.

    }
>
> As you can see in case one helper function it is easy to manipulate and
> use it, but in case of a lot of functions it would be better to support
> some kind of extension methods:
>
>     namespace IPCBus {
>       class IClient {
>         public:
>           ... // Other member functions
>           template &lt;typename TClient&gt;
>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>             auto client =3D std::shared_ptr(new TClient);
>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE SKIPE=
D
> !!
>             return client;
>           }
>         protected:
>           Client() =3D default;
>       };
>
>       template &lt;typename T, typename ... TArgs&gt;
>       std::shared_ptr&lt;T&gt; make_shared(TArgs&&... _args) {
>         return IClient::buildClient(std::forward&lt;TArgs&gt;(_args)...);
>       }
>

This, if in scope, would likely be ambiguous with std::make_shared. And if
you make it a better overload candidate, it would hijack all make_shared
calls that should invoke std::make_shared. Adding an overload to someone
else's overload set, when they didn't design for their overload set to be
extensible, is a very bad design practice.


>     }  // namespace IPCBus
>
>     class RealClient : public IClient {
>       public:
>        RealClient()
>          : IClient() {
>        }
>     };
>
>     using namespace std;
>
>     int main() {
>       auto realClient =3D make_shared&lt;RealClient&gt;();
>       // We use our own version of make_shared that is delegate creation
> of object to builder method
>       // Cool !!
>     }
>
> As *Herb Sutter* said at *CppCon 2017: Herb Sutter =E2=80=9CMeta: Thought=
s on
> generative C++=E2=80=9D*:
> "Abstraction are hiders by definition. If they did not do this they are
> useless ..."
> "It's not the problem. It is the point."
>
> I see this suggestion to extend *ADL* search on caller object and on
> template parameter as simplifier for Library Writters and also General
> Programmers
>

I don't agree at all with your motivation, but nonetheless I do agree with
your conclusion: it does seem reasonable for ADL to consider associated
classes and namespaces of template arguments in the case where the function
name is a template-id. I suspect this was not done previously because the
callee in a function call for which ADL is performed was very rarely a
template-id prior to P0846R0, but now we've adopted that paper for C++20,
it would make sense to take the associated classes and namespaces of the
template arguments into account, and especially because we now allow
objects of class type as non-type template arguments:

namespace N {
  struct Params { /*...*/ };
  auto make_dynamic(Params P) { /*...*/ }
  template<Params P> auto make_static() { /*...*/ }
}
auto x =3D make_dynamic(N::Params{1, 2, 3}); // OK
auto y =3D make_static<N::Params{1, 2, 3}>(); // error today, could be vali=
d
tomorrow

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAOfiQqm-U3tn%3DyC2ZRnacJbq2hx4bq1p7Da7HpCO4ZD3Y=
e_%3DnA%40mail.gmail.com.

--0000000000000d22c60577d1952d
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div class=3D"gmail_quot=
e"><div dir=3D"ltr">On Tue, 9 Oct 2018 at 11:11, Denis Kotov &lt;<a href=3D=
"mailto:redradist@gmail.com">redradist@gmail.com</a>&gt; wrote:<br></div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Hello=
 everyone,</div><div><br></div><div>I have prepared the proposal for extend=
ing an ADL search algorithm:</div><div><br></div><div><b>Propousal for exte=
nsion methods like.</b> Lets consider the following example:</div><div><br>=
</div><div>=C2=A0=C2=A0=C2=A0 namespace DeviceManager {<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 class Device {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... /=
/ Other member functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 uint32_t getId() const {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 private:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // =
Other member variables<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 uint32_t id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 using DeviceList =3D std::vector&amp;lt;Device&amp;gt=
;;<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Device mergeDeviceInfo(const Devic=
e &amp; _first, const Device &amp; _second) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 ... // Implementation<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
}<br>=C2=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::DeviceList deviceList;<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 ... // Some work<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 au=
to foundDeviceIter0 =3D std::find_if(deviceList.begin(), deviceList.end(), =
[=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some first cre=
teria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 auto foundDeviceIter1 =3D std::find_if(deviceList.begin(), deviceList.e=
nd(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some sec=
ond creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 if (deviceList.end() !=3D foundDeviceIter0 &amp;&amp; deviceList.=
end() !=3D foundDeviceIter1) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 DeviceManager::Device mergedDevice =3D DeviceManager::mergeDeviceInfo(*=
foundDeviceIter0, *foundDeviceIter1);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 ... // Some other work<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=
=A0=C2=A0=C2=A0 }</div><div><br></div><div>As you can see in case one helpe=
r function it is easy to manipulate and use it, but in case of a lot of fun=
ctions it would be better to support some kind of extension methods:</div><=
div><br></div><div>namespace DeviceManager {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 class Device {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br=
>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other member=
 functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32=
_t getId() const {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 return id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 private:<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other member =
variables<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_=
t id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 using DeviceList =3D std::vector&amp;lt;Device&amp;gt;;<br><br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 1. If it is called by reference type prefer =
this overload function<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Device mergeDevice=
Info(const Device &amp; _first, const Device &amp; _second) {<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Implementation<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 2. If it is called b=
y pointer type prefer this overload function<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 Device mergeDeviceInfo(const Device * _firstPtr, const Device * _second=
Ptr) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Implementation<=
br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }<br><br>=C2=A0=
=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::=
DeviceList deviceList;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some work<b=
r>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto foundDeviceIter0 =3D std::find_if(dev=
iceList.begin(), deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 ... // Some first creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto foundDeviceIter1 =3D std::fi=
nd_if(deviceList.begin(), deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some second creteria<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (deviceList.end() !=
=3D foundDeviceIter0 &amp;&amp; deviceList.end() !=3D foundDeviceIter1) {<b=
r>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 1. Overload function for re=
ferences if called<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ADL wil=
l search in dependent scopes also for calling functions by object reference=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device &amp; =
firstFoundDevice =3D *foundDeviceIter0;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 DeviceManager::Device &amp; secondFoundDevice =3D *foundDevice=
Iter1;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device =
mergedDevice =3D firstFoundDevice.mergeDeviceInfo(secondFoundDevice);<br><b=
r>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 2. Overload function for po=
inters if called<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ADL will =
search in dependent scopes lso for calling functions by object pointer<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device mergedDevi=
ce =3D foundDeviceIter0-&gt;mergeDeviceInfo(*foundDeviceIter1);<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some other work<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }</div><div><br></div><div><b>Pr=
opousal for extension of ADL on template parameter.</b> Lets consider the f=
ollowing example:</div><div><br></div><div>=C2=A0=C2=A0=C2=A0 namespace IPC=
Bus {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class IClient {<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 ... // Other member functions<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 template &amp;lt;typename TClient&amp;gt;=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static std::shar=
ed_ptr&amp;lt;IClient&amp;gt; buildClient() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto client =3D std::shared_ptr(=
new TClient);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE SKIPED !!=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 retu=
rn client;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 protected:<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Client() =3D default;<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 };<br>=C2=A0=C2=A0=C2=A0 }=C2=A0 // namespace IPCBus<br>=
<br>=C2=A0=C2=A0=C2=A0 class RealClient : public IClient {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 RealClie=
nt()<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 : IClient() {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 };<br><br>=C2=
=A0=C2=A0=C2=A0 using namespace std;<br><br>=C2=A0=C2=A0=C2=A0 int main() {=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto realClient =3D make_shared&amp;lt;R=
ealClient&amp;gt;();<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // WE MISSED THE VER=
Y IMPORTANT STEPS IN CREATION OF OBJECT !!<br></div></div></blockquote><div=
><br></div><div>If you don&#39;t want RealClient instances to be created by=
 calling the default constructor, the default constructor should not be pub=
lic. There are other techniques you can use to allow IClient to create inst=
ances of RealClient without exposing a public default constructor that crea=
tes a broken object. Your approach doesn&#39;t stop someone from doing this=
:</div><div><br></div><div>=C2=A0 make_unique&lt;RealClient&gt;() // still =
broken</div><div><br></div><div>or this:</div><div><br></div><div>=C2=A0 st=
d::make_shared&lt;RealClient&gt;() // still broken</div><div><br></div><div=
>It&#39;s also broken by the intent of P0551R3 (adopted for C++20), which i=
ntends to make it possible to implement standard library functions as funct=
ion objects instead of as real functions, and by P0921R2, which says that y=
ou can&#39;t rely on (for instance) how a standard-library function will pa=
rtially order with respect to a function of your own.</div><div><br></div><=
div>So I don&#39;t think this approach really solves the problem you&#39;re=
 trying to address, especially not when used to subvert calls to standard l=
ibrary functions.</div><div><br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddi=
ng-left:1ex"><div dir=3D"ltr"><div>=C2=A0=C2=A0=C2=A0 }</div><div><br></div=
><div>As you can see in case one helper function it is easy to manipulate a=
nd use it, but in case of a lot of functions it would be better to support =
some kind of extension methods:</div><div><br></div><div>=C2=A0=C2=A0=C2=A0=
 namespace IPCBus {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class IClient {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other member functions<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 template &amp;lt;typename =
TClient&amp;gt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 s=
tatic std::shared_ptr&amp;lt;IClient&amp;gt; buildClient() {<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto client =3D s=
td::shared_ptr(new TClient);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 ... // IMPORTANT THINGS AFTER INITIALIZATION. CANN=
OT BE SKIPED !!<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 return client;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 protected:<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Client() =3D default=
;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 template &amp;lt;typename T, typename ... TArgs&amp;gt;<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 std::shared_ptr&amp;lt;T&amp;gt; make_shared(TArgs&amp;&=
amp;... _args) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return IClie=
nt::buildClient(std::forward&amp;lt;TArgs&amp;gt;(_args)...);<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 }<br></div></div></blockquote><div><br></div><div>Thi=
s, if in scope, would likely be ambiguous with std::make_shared. And if you=
 make it a better overload candidate, it would hijack all make_shared calls=
 that should invoke std::make_shared. Adding an overload to someone else&#3=
9;s overload set, when they didn&#39;t design for their overload set to be =
extensible, is a very bad design practice.</div><div>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px s=
olid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>=C2=A0=C2=A0=
=C2=A0 }=C2=A0 // namespace IPCBus<br><br>=C2=A0=C2=A0=C2=A0 class RealClie=
nt : public IClient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 RealClient()<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 : IClient() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 }<br>=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0 using namespace std;<=
br><br>=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 au=
to realClient =3D make_shared&amp;lt;RealClient&amp;gt;();<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 // We use our own version of make_shared that is delegat=
e creation of object to builder method<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 //=
 Cool !!<br>=C2=A0=C2=A0=C2=A0 }</div><div><br></div><div>As <b>Herb Sutter=
</b> said at <b>CppCon 2017: Herb Sutter =E2=80=9CMeta: Thoughts on generat=
ive C++=E2=80=9D</b>:<br>&quot;Abstraction are hiders by definition. If the=
y did not do this they are useless ...&quot;<br>&quot;It&#39;s not the prob=
lem. It is the point.&quot;<br><br>I see this suggestion to extend <b>ADL</=
b> search on caller object and on template parameter as simplifier for Libr=
ary Writters and also General Programmers</div></div></blockquote><div><br>=
</div><div>I don&#39;t agree at all with your motivation, but nonetheless I=
 do agree with your conclusion: it does seem reasonable for ADL to consider=
 associated classes and namespaces of template arguments in the case where =
the function name is a template-id. I suspect this was not done previously =
because the callee in a function call for which ADL is performed was very r=
arely a template-id prior to P0846R0, but now we&#39;ve adopted that paper =
for C++20, it would make sense to take the associated classes and namespace=
s of the template arguments into account, and especially because we now all=
ow objects of class type as non-type template arguments:</div><div><br></di=
v><div>namespace N {</div><div>=C2=A0 struct Params { /*...*/ };</div><div>=
=C2=A0 auto make_dynamic(Params P) { /*...*/ }<br></div><div>=C2=A0 templat=
e&lt;Params P&gt; auto make_static() { /*...*/ }</div><div>}<br></div><div>=
auto x =3D make_dynamic(N::Params{1, 2, 3}); // OK</div><div>auto y =3D mak=
e_static&lt;N::Params{1, 2, 3}&gt;(); // error today, could be valid tomorr=
ow</div></div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQqm-U3tn%3DyC2ZRnacJbq2hx4bq1p7D=
a7HpCO4ZD3Ye_%3DnA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqm-U3tn=
%3DyC2ZRnacJbq2hx4bq1p7Da7HpCO4ZD3Ye_%3DnA%40mail.gmail.com</a>.<br />

--0000000000000d22c60577d1952d--

.


Author: =?UTF-8?B?R2HFoXBlciBBxb5tYW4=?= <gasper.azman@gmail.com>
Date: Tue, 9 Oct 2018 21:31:12 +0100
Raw View
--00000000000007b8410577d19fd3
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hi Denis,

You might want to include a link to a rendered version of the HTML on your
github. I would also suggest using bikeshed (
https://github.com/tabatkins/bikeshed ) to write it, as you will get
automatic code highlighting and help with specifying the various needed
sections. This will make it easier for everyone to read your proposal.

As an example, here is a published one:
https://atomgalaxy.github.io/brevzin-wg21/0847_deducing_this/p0847r1.html
The source is here (enable github sites to get it to display properly):
https://github.com/atomgalaxy/brevzin-wg21/tree/master/0847_deducing_this

Everyone will thank you :).

Ga=C5=A1per

On Tue, Oct 9, 2018 at 7:16 PM Denis Kotov <redradist@gmail.com> wrote:

> This proposal is available on GitHub also
> https://github.com/redradist/cpp_standard_propousals/blob/master/ADL%20Ex=
tension.html
>
> =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 9 =D0=BE=D0=BA=D1=82=D1=8F=D0=
=B1=D1=80=D1=8F 2018 =D0=B3., 21:11:13 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=
=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Denis Kotov
> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>
>> Hello everyone,
>>
>> I have prepared the proposal for extending an ADL search algorithm:
>>
>> *Propousal for extension methods like.* Lets consider the following
>> example:
>>
>>     namespace DeviceManager {
>>       class Device {
>>         public:
>>           ... // Other member functions
>>           uint32_t getId() const {
>>             return id_;
>>           }
>>         private:
>>           ... // Other member variables
>>           uint32_t id_;
>>       };
>>
>>       using DeviceList =3D std::vector&lt;Device&gt;;
>>
>>       Device mergeDeviceInfo(const Device & _first, const Device &
>> _second) {
>>         ... // Implementation
>>       }
>>     }
>>
>>     int main() {
>>       DeviceManager::DeviceList deviceList;
>>       ... // Some work
>>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),
>> deviceList.end(), [=3D] {
>>         ... // Some first creteria
>>       });
>>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),
>> deviceList.end(), [=3D] {
>>         ... // Some second creteria
>>       });
>>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=
=3D
>> foundDeviceIter1) {
>>         DeviceManager::Device mergedDevice =3D
>> DeviceManager::mergeDeviceInfo(*foundDeviceIter0, *foundDeviceIter1);
>>         ... // Some other work
>>       }
>>     }
>>
>> As you can see in case one helper function it is easy to manipulate and
>> use it, but in case of a lot of functions it would be better to support
>> some kind of extension methods:
>>
>> namespace DeviceManager {
>>       class Device {
>>         public:
>>           ... // Other member functions
>>           uint32_t getId() const {
>>             return id_;
>>           }
>>         private:
>>           ... // Other member variables
>>           uint32_t id_;
>>       };
>>
>>       using DeviceList =3D std::vector&lt;Device&gt;;
>>
>>       // 1. If it is called by reference type prefer this overload
>> function
>>       Device mergeDeviceInfo(const Device & _first, const Device &
>> _second) {
>>         ... // Implementation
>>       }
>>       // 2. If it is called by pointer type prefer this overload functio=
n
>>       Device mergeDeviceInfo(const Device * _firstPtr, const Device *
>> _secondPtr) {
>>         ... // Implementation
>>       }
>>     }
>>
>>     int main() {
>>       DeviceManager::DeviceList deviceList;
>>       ... // Some work
>>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),
>> deviceList.end(), [=3D] {
>>         ... // Some first creteria
>>       });
>>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),
>> deviceList.end(), [=3D] {
>>         ... // Some second creteria
>>       });
>>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=
=3D
>> foundDeviceIter1) {
>>         // 1. Overload function for references if called
>>         // ADL will search in dependent scopes also for calling function=
s
>> by object reference
>>         DeviceManager::Device & firstFoundDevice =3D *foundDeviceIter0;
>>         DeviceManager::Device & secondFoundDevice =3D *foundDeviceIter1;
>>         DeviceManager::Device mergedDevice =3D
>> firstFoundDevice.mergeDeviceInfo(secondFoundDevice);
>>
>>         // 2. Overload function for pointers if called
>>         // ADL will search in dependent scopes lso for calling functions
>> by object pointer
>>         DeviceManager::Device mergedDevice =3D
>> foundDeviceIter0->mergeDeviceInfo(*foundDeviceIter1);
>>         ... // Some other work
>>       }
>>     }
>>
>> *Propousal for extension of ADL on template parameter.* Lets consider
>> the following example:
>>
>>     namespace IPCBus {
>>       class IClient {
>>         public:
>>           ... // Other member functions
>>           template &lt;typename TClient&gt;
>>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>>             auto client =3D std::shared_ptr(new TClient);
>>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE
>> SKIPED !!
>>             return client;
>>           }
>>         protected:
>>           Client() =3D default;
>>       };
>>     }  // namespace IPCBus
>>
>>     class RealClient : public IClient {
>>       public:
>>        RealClient()
>>          : IClient() {
>>        }
>>     };
>>
>>     using namespace std;
>>
>>     int main() {
>>       auto realClient =3D make_shared&lt;RealClient&gt;();
>>       // WE MISSED THE VERY IMPORTANT STEPS IN CREATION OF OBJECT !!
>>     }
>>
>> As you can see in case one helper function it is easy to manipulate and
>> use it, but in case of a lot of functions it would be better to support
>> some kind of extension methods:
>>
>>     namespace IPCBus {
>>       class IClient {
>>         public:
>>           ... // Other member functions
>>           template &lt;typename TClient&gt;
>>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>>             auto client =3D std::shared_ptr(new TClient);
>>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE
>> SKIPED !!
>>             return client;
>>           }
>>         protected:
>>           Client() =3D default;
>>       };
>>
>>       template &lt;typename T, typename ... TArgs&gt;
>>       std::shared_ptr&lt;T&gt; make_shared(TArgs&&... _args) {
>>         return IClient::buildClient(std::forward&lt;TArgs&gt;(_args)...)=
;
>>       }
>>     }  // namespace IPCBus
>>
>>     class RealClient : public IClient {
>>       public:
>>        RealClient()
>>          : IClient() {
>>        }
>>     };
>>
>>     using namespace std;
>>
>>     int main() {
>>       auto realClient =3D make_shared&lt;RealClient&gt;();
>>       // We use our own version of make_shared that is delegate creation
>> of object to builder method
>>       // Cool !!
>>     }
>>
>> As *Herb Sutter* said at *CppCon 2017: Herb Sutter =E2=80=9CMeta: Though=
ts on
>> generative C++=E2=80=9D*:
>> "Abstraction are hiders by definition. If they did not do this they are
>> useless ..."
>> "It's not the problem. It is the point."
>>
>> I see this suggestion to extend *ADL* search on caller object and on
>> template parameter as simplifier for Library Writters and also General
>> Programmers
>>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cf51a959-42d=
4-42c5-9e25-1455681402ff%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cf51a959-42=
d4-42c5-9e25-1455681402ff%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAANG%3DkXQq2jmmDmrbmTe19hhF4Ya8QXX-a7amEz4kiZEa=
dD7cQ%40mail.gmail.com.

--00000000000007b8410577d19fd3
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr">Hi Deni=
s,<div><br></div><div>You might want to include a link to a rendered versio=
n of the HTML on your github. I would also suggest using bikeshed ( <a href=
=3D"https://github.com/tabatkins/bikeshed">https://github.com/tabatkins/bik=
eshed</a> ) to write it, as you will get automatic code highlighting and he=
lp with specifying the various needed sections. This will make it easier fo=
r everyone to read your proposal.</div><div><br></div><div>As an example, h=
ere is a published one:</div><div><a href=3D"https://atomgalaxy.github.io/b=
revzin-wg21/0847_deducing_this/p0847r1.html">https://atomgalaxy.github.io/b=
revzin-wg21/0847_deducing_this/p0847r1.html</a></div><div>The source is her=
e (enable github sites to get it to display properly):=C2=A0<a href=3D"http=
s://github.com/atomgalaxy/brevzin-wg21/tree/master/0847_deducing_this">http=
s://github.com/atomgalaxy/brevzin-wg21/tree/master/0847_deducing_this</a></=
div><div><br></div><div>Everyone will thank you :).</div><div><br></div><di=
v>Ga=C5=A1per</div></div></div></div></div><br><div class=3D"gmail_quote"><=
div dir=3D"ltr">On Tue, Oct 9, 2018 at 7:16 PM Denis Kotov &lt;<a href=3D"m=
ailto:redradist@gmail.com">redradist@gmail.com</a>&gt; wrote:<br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr">This proposal is available on G=
itHub also <a href=3D"https://github.com/redradist/cpp_standard_propousals/=
blob/master/ADL%20Extension.html" target=3D"_blank">https://github.com/redr=
adist/cpp_standard_propousals/blob/master/ADL%20Extension.html</a> <br><br>=
=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 9 =D0=BE=D0=BA=D1=82=D1=8F=D0=
=B1=D1=80=D1=8F 2018 =D0=B3., 21:11:13 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=
=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Denis Kotov =D0=BD=D0=B0=D0=BF=
=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>Hello everyone,</div><div><br></div><div>I have prepared the =
proposal for extending an ADL search algorithm:</div><div><br></div><div><b=
>Propousal for extension methods like.</b> Lets consider the following exam=
ple:</div><div><br></div><div>=C2=A0=C2=A0=C2=A0 namespace DeviceManager {<=
br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class Device {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 ... // Other member functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t getId() const {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return id_;<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 private:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 ... // Other member variables<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 };<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using DeviceList =3D std::vector&=
amp;lt;Device&amp;gt;;<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Device mergeDe=
viceInfo(const Device &amp; _first, const Device &amp; _second) {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Implementation<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 int =
main() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::DeviceList device=
List;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some work<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 auto foundDeviceIter0 =3D std::find_if(deviceList.begin(), =
deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ...=
 // Some first creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 auto foundDeviceIter1 =3D std::find_if(deviceList.beg=
in(), deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 ... // Some second creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (deviceList.end() !=3D foundDeviceIter0 &=
amp;&amp; deviceList.end() !=3D foundDeviceIter1) {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device mergedDevice =3D DeviceManag=
er::mergeDeviceInfo(*foundDeviceIter0, *foundDeviceIter1);<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some other work<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }</div><div><br></div><div>As you can =
see in case one helper function it is easy to manipulate and use it, but in=
 case of a lot of functions it would be better to support some kind of exte=
nsion methods:</div><div><br></div><div>namespace DeviceManager {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 class Device {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 ... // Other member functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 uint32_t getId() const {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return id_;<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 private:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 ... // Other member variables<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 uint32_t id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br><b=
r>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using DeviceList =3D std::vector&amp;lt;De=
vice&amp;gt;;<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 1. If it is called b=
y reference type prefer this overload function<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 Device mergeDeviceInfo(const Device &amp; _first, const Device &amp;=
 _second) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Implementa=
tion<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
// 2. If it is called by pointer type prefer this overload function<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 Device mergeDeviceInfo(const Device * _firstPtr=
, const Device * _secondPtr) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 ... // Implementation<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=
=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 DeviceManager::DeviceList deviceList;<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 ... // Some work<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto foundDeviceI=
ter0 =3D std::find_if(deviceList.begin(), deviceList.end(), [=3D] {<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some first creteria<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto foun=
dDeviceIter1 =3D std::find_if(deviceList.begin(), deviceList.end(), [=3D] {=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some second creteria<=
br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if =
(deviceList.end() !=3D foundDeviceIter0 &amp;&amp; deviceList.end() !=3D fo=
undDeviceIter1) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 1. Overl=
oad function for references if called<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 // ADL will search in dependent scopes also for calling functions=
 by object reference<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceMa=
nager::Device &amp; firstFoundDevice =3D *foundDeviceIter0;<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device &amp; secondFoundDevic=
e =3D *foundDeviceIter1;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Devi=
ceManager::Device mergedDevice =3D firstFoundDevice.mergeDeviceInfo(secondF=
oundDevice);<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 2. Overlo=
ad function for pointers if called<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 // ADL will search in dependent scopes lso for calling functions by =
object pointer<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager:=
:Device mergedDevice =3D foundDeviceIter0-&gt;mergeDeviceInfo(*foundDeviceI=
ter1);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some other work=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }</div><div><br>=
</div><div><b>Propousal for extension of ADL on template parameter.</b> Let=
s consider the following example:</div><div><br></div><div>=C2=A0=C2=A0=C2=
=A0 namespace IPCBus {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class IClient {<br=
>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other member functions<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 template &amp;lt;typena=
me TClient&amp;gt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 static std::shared_ptr&amp;lt;IClient&amp;gt; buildClient() {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto client =
=3D std::shared_ptr(new TClient);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // IMPORTANT THINGS AFTER INITIALIZATION=
.. CANNOT BE SKIPED !!<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 return client;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 protecte=
d:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Client() =3D d=
efault;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br>=C2=A0=C2=A0=C2=A0 }=C2=A0 =
// namespace IPCBus<br><br>=C2=A0=C2=A0=C2=A0 class RealClient : public ICl=
ient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 RealClient()<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 : IClient() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=
=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0 using namespace std;<br><br>=C2=A0=
=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto realClient=
 =3D make_shared&amp;lt;RealClient&amp;gt;();<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 // WE MISSED THE VERY IMPORTANT STEPS IN CREATION OF OBJECT !!<br>=
=C2=A0=C2=A0=C2=A0 }</div><div><br></div><div>As you can see in case one he=
lper function it is easy to manipulate and use it, but in case of a lot of =
functions it would be better to support some kind of extension methods:</di=
v><div><br></div><div>=C2=A0=C2=A0=C2=A0 namespace IPCBus {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 class IClient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ..=
.. // Other member functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 template &amp;lt;typename TClient&amp;gt;<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static std::shared_ptr&amp;lt;IClie=
nt&amp;gt; buildClient() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 auto client =3D std::shared_ptr(new TClient);<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // IMPO=
RTANT THINGS AFTER INITIALIZATION. CANNOT BE SKIPED !!<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return client;<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 protected:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 Client() =3D default;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
};<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 template &amp;lt;typename T, typen=
ame ... TArgs&amp;gt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 std::shared_ptr&amp=
;lt;T&amp;gt; make_shared(TArgs&amp;&amp;... _args) {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 return IClient::buildClient(std::forward&amp;lt;TA=
rgs&amp;gt;(_args)...);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=
=C2=A0 }=C2=A0 // namespace IPCBus<br><br>=C2=A0=C2=A0=C2=A0 class RealClie=
nt : public IClient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 RealClient()<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 : IClient() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 }<br>=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0 using namespace std;<=
br><br>=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 au=
to realClient =3D make_shared&amp;lt;RealClient&amp;gt;();<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 // We use our own version of make_shared that is delegat=
e creation of object to builder method<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 //=
 Cool !!<br>=C2=A0=C2=A0=C2=A0 }</div><div><br></div><div>As <b>Herb Sutter=
</b> said at <b>CppCon 2017: Herb Sutter =E2=80=9CMeta: Thoughts on generat=
ive C++=E2=80=9D</b>:<br>&quot;Abstraction are hiders by definition. If the=
y did not do this they are useless ...&quot;<br>&quot;It&#39;s not the prob=
lem. It is the point.&quot;<br><br>I see this suggestion to extend <b>ADL</=
b> search on caller object and on template parameter as simplifier for Libr=
ary Writters and also General Programmers<br></div></div></blockquote></div=
>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/cf51a959-42d4-42c5-9e25-1455681402ff%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cf51a959-42d4-=
42c5-9e25-1455681402ff%40isocpp.org</a>.<br>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAANG%3DkXQq2jmmDmrbmTe19hhF4Ya8QXX-a=
7amEz4kiZEadD7cQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAANG%3DkXQq2jm=
mDmrbmTe19hhF4Ya8QXX-a7amEz4kiZEadD7cQ%40mail.gmail.com</a>.<br />

--00000000000007b8410577d19fd3--

.


Author: Denis Kotov <redradist@gmail.com>
Date: Wed, 10 Oct 2018 00:11:53 -0700 (PDT)
Raw View
------=_Part_2503_278951322.1539155513558
Content-Type: multipart/alternative;
 boundary="----=_Part_2504_973252305.1539155513559"

------=_Part_2504_973252305.1539155513559
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hello Richard,

With make_shared it was just an example, but nonetheless I wanted to make=
=20
*ADL* look-up on template parameter dependent scope just for more=20
flexibility for developer
I appreciate that you like the idea for searching on template parameter

What about my* first proposal* ? About extension methods:

    namespace DeviceManager {
      class Device {
        public:
          ... // Other member functions
          uint32_t getId() const {
            return id_;
          }
        private:
          ... // Other member variables
          uint32_t id_;
      };

      using DeviceList =3D std::vector<Device>;

      // 1. If it is called by reference type prefer this overload function
      Device mergeDeviceInfo(const Device & _first, const Device & _second)=
=20
{
        ... // Implementation
      }
      // 2. If it is called by pointer type prefer this overload function
      Device mergeDeviceInfo(const Device * _firstPtr, const Device *=20
_secondPtr) {
        ... // Implementation
      }
    }

    int main() {
      DeviceManager::DeviceList deviceList;
      ... // Some work
      auto founFirstDeviceIter =3D std::find_if(deviceList.begin(
), deviceList.end(), [=3D] {
        ... // Some first creteria
      });
      auto foundSecondDeviceIter =3D std::find_if(deviceList.begin(),=20
deviceList.end(), [=3D] {
        ... // Some second creteria
      });
      if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=3D=
=20
foundDeviceIter1) {
       =20
        DeviceManager::Device & firstFoundDevice =3D *founFirstDeviceIter;
        DeviceManager::Device & secondFoundDevice =3D *foundSecondDeviceIte=
r;

       =20
*// Extension method example 1: Overload function for references if=20
called        // ADL will search in dependent scopes also for calling=20
functions by object reference*
        DeviceManager::Device mergedDevice =3D* firstFoundDevice.*
*mergeDeviceInfo(**secondFoundDevice); **// Extension method instead of *
*DeviceManager::**mergeDeviceInfo(**firstFoundDevice**,** secondFoundDevice=
*
*)*

       =20
*// Extension method example 2: Overload function for pointers if=20
called        // ADL will search in dependent scopes lso for calling=20
functions by object pointer*
        DeviceManager::Device mergedDevice =3D *founFirstDeviceIter->*
*mergeDeviceInfo(***foundDeviceIter1); // **Extension method instead of *
*DeviceManager::**mergeDeviceInfo(**founFirstDeviceIter, **foundDeviceIter1=
*
*)*

        ... // Some other work
      }
    }

What do you think ?

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 9 =D0=BE=D0=BA=D1=82=D1=8F=D0=
=B1=D1=80=D1=8F 2018 =D0=B3., 23:28:42 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=
=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Richard Smith=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> On Tue, 9 Oct 2018 at 11:11, Denis Kotov <redr...@gmail.com <javascript:>=
>=20
> wrote:
>
>> Hello everyone,
>>
>> I have prepared the proposal for extending an ADL search algorithm:
>>
>> *Propousal for extension methods like.* Lets consider the following=20
>> example:
>>
>>     namespace DeviceManager {
>>       class Device {
>>         public:
>>           ... // Other member functions
>>           uint32_t getId() const {
>>             return id_;
>>           }
>>         private:
>>           ... // Other member variables
>>           uint32_t id_;
>>       };
>>
>>       using DeviceList =3D std::vector&lt;Device&gt;;
>>
>>       Device mergeDeviceInfo(const Device & _first, const Device &=20
>> _second) {
>>         ... // Implementation
>>       }
>>     }
>>
>>     int main() {
>>       DeviceManager::DeviceList deviceList;
>>       ... // Some work
>>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),=20
>> deviceList.end(), [=3D] {
>>         ... // Some first creteria
>>       });
>>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),=20
>> deviceList.end(), [=3D] {
>>         ... // Some second creteria
>>       });
>>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=
=3D=20
>> foundDeviceIter1) {
>>         DeviceManager::Device mergedDevice =3D=20
>> DeviceManager::mergeDeviceInfo(*foundDeviceIter0, *foundDeviceIter1);
>>         ... // Some other work
>>       }
>>     }
>>
>> As you can see in case one helper function it is easy to manipulate and=
=20
>> use it, but in case of a lot of functions it would be better to support=
=20
>> some kind of extension methods:
>>
>> namespace DeviceManager {
>>       class Device {
>>         public:
>>           ... // Other member functions
>>           uint32_t getId() const {
>>             return id_;
>>           }
>>         private:
>>           ... // Other member variables
>>           uint32_t id_;
>>       };
>>
>>       using DeviceList =3D std::vector&lt;Device&gt;;
>>
>>       // 1. If it is called by reference type prefer this overload=20
>> function
>>       Device mergeDeviceInfo(const Device & _first, const Device &=20
>> _second) {
>>         ... // Implementation
>>       }
>>       // 2. If it is called by pointer type prefer this overload functio=
n
>>       Device mergeDeviceInfo(const Device * _firstPtr, const Device *=20
>> _secondPtr) {
>>         ... // Implementation
>>       }
>>     }
>>
>>     int main() {
>>       DeviceManager::DeviceList deviceList;
>>       ... // Some work
>>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),=20
>> deviceList.end(), [=3D] {
>>         ... // Some first creteria
>>       });
>>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),=20
>> deviceList.end(), [=3D] {
>>         ... // Some second creteria
>>       });
>>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=
=3D=20
>> foundDeviceIter1) {
>>         // 1. Overload function for references if called
>>         // ADL will search in dependent scopes also for calling function=
s=20
>> by object reference
>>         DeviceManager::Device & firstFoundDevice =3D *foundDeviceIter0;
>>         DeviceManager::Device & secondFoundDevice =3D *foundDeviceIter1;
>>         DeviceManager::Device mergedDevice =3D=20
>> firstFoundDevice.mergeDeviceInfo(secondFoundDevice);
>>
>>         // 2. Overload function for pointers if called
>>         // ADL will search in dependent scopes lso for calling functions=
=20
>> by object pointer
>>         DeviceManager::Device mergedDevice =3D=20
>> foundDeviceIter0->mergeDeviceInfo(*foundDeviceIter1);
>>         ... // Some other work
>>       }
>>     }
>>
>> *Propousal for extension of ADL on template parameter.* Lets consider=20
>> the following example:
>>
>>     namespace IPCBus {
>>       class IClient {
>>         public:
>>           ... // Other member functions
>>           template &lt;typename TClient&gt;
>>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>>             auto client =3D std::shared_ptr(new TClient);
>>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE=20
>> SKIPED !!
>>             return client;
>>           }
>>         protected:
>>           Client() =3D default;
>>       };
>>     }  // namespace IPCBus
>>
>>     class RealClient : public IClient {
>>       public:
>>        RealClient()
>>          : IClient() {
>>        }
>>     };
>>
>>     using namespace std;
>>
>>     int main() {
>>       auto realClient =3D make_shared&lt;RealClient&gt;();
>>       // WE MISSED THE VERY IMPORTANT STEPS IN CREATION OF OBJECT !!
>>
>
> If you don't want RealClient instances to be created by calling the=20
> default constructor, the default constructor should not be public. There=
=20
> are other techniques you can use to allow IClient to create instances of=
=20
> RealClient without exposing a public default constructor that creates a=
=20
> broken object. Your approach doesn't stop someone from doing this:
>
>   make_unique<RealClient>() // still broken
>
> or this:
>
>   std::make_shared<RealClient>() // still broken
>
> It's also broken by the intent of P0551R3 (adopted for C++20), which=20
> intends to make it possible to implement standard library functions as=20
> function objects instead of as real functions, and by P0921R2, which says=
=20
> that you can't rely on (for instance) how a standard-library function wil=
l=20
> partially order with respect to a function of your own.
>
> So I don't think this approach really solves the problem you're trying to=
=20
> address, especially not when used to subvert calls to standard library=20
> functions.
>
>     }
>>
>> As you can see in case one helper function it is easy to manipulate and=
=20
>> use it, but in case of a lot of functions it would be better to support=
=20
>> some kind of extension methods:
>>
>>     namespace IPCBus {
>>       class IClient {
>>         public:
>>           ... // Other member functions
>>           template &lt;typename TClient&gt;
>>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>>             auto client =3D std::shared_ptr(new TClient);
>>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE=20
>> SKIPED !!
>>             return client;
>>           }
>>         protected:
>>           Client() =3D default;
>>       };
>>
>>       template &lt;typename T, typename ... TArgs&gt;
>>       std::shared_ptr&lt;T&gt; make_shared(TArgs&&... _args) {
>>         return IClient::buildClient(std::forward&lt;TArgs&gt;(_args)...)=
;
>>       }
>>
>
> This, if in scope, would likely be ambiguous with std::make_shared. And i=
f=20
> you make it a better overload candidate, it would hijack all make_shared=
=20
> calls that should invoke std::make_shared. Adding an overload to someone=
=20
> else's overload set, when they didn't design for their overload set to be=
=20
> extensible, is a very bad design practice.
> =20
>
>>     }  // namespace IPCBus
>>
>>     class RealClient : public IClient {
>>       public:
>>        RealClient()
>>          : IClient() {
>>        }
>>     };
>>
>>     using namespace std;
>>
>>     int main() {
>>       auto realClient =3D make_shared&lt;RealClient&gt;();
>>       // We use our own version of make_shared that is delegate creation=
=20
>> of object to builder method
>>       // Cool !!
>>     }
>>
>> As *Herb Sutter* said at *CppCon 2017: Herb Sutter =E2=80=9CMeta: Though=
ts on=20
>> generative C++=E2=80=9D*:
>> "Abstraction are hiders by definition. If they did not do this they are=
=20
>> useless ..."
>> "It's not the problem. It is the point."
>>
>> I see this suggestion to extend *ADL* search on caller object and on=20
>> template parameter as simplifier for Library Writters and also General=
=20
>> Programmers
>>
>
> I don't agree at all with your motivation, but nonetheless I do agree wit=
h=20
> your conclusion: it does seem reasonable for ADL to consider associated=
=20
> classes and namespaces of template arguments in the case where the functi=
on=20
> name is a template-id. I suspect this was not done previously because the=
=20
> callee in a function call for which ADL is performed was very rarely a=20
> template-id prior to P0846R0, but now we've adopted that paper for C++20,=
=20
> it would make sense to take the associated classes and namespaces of the=
=20
> template arguments into account, and especially because we now allow=20
> objects of class type as non-type template arguments:
>
> namespace N {
>   struct Params { /*...*/ };
>   auto make_dynamic(Params P) { /*...*/ }
>   template<Params P> auto make_static() { /*...*/ }
> }
> auto x =3D make_dynamic(N::Params{1, 2, 3}); // OK
> auto y =3D make_static<N::Params{1, 2, 3}>(); // error today, could be va=
lid=20
> tomorrow
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/9579b759-d5c0-41c9-a224-5c54fcf88274%40isocpp.or=
g.

------=_Part_2504_973252305.1539155513559
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hello Richard,</div><div><br></div><div>With make_sha=
red it was just an example, but nonetheless I wanted to make <b>ADL</b> loo=
k-up on template parameter dependent scope just for more flexibility for de=
veloper</div><div>I appreciate that you like the idea for searching on temp=
late parameter<br></div><div><br></div><div>What about my<b> first proposal=
</b> ? About extension methods:</div><div><br></div><div>=C2=A0=C2=A0=C2=A0=
 namespace DeviceManager {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class Device {=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other member functions<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t getId() con=
st {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
return id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 private:<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other member variables<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t id_;<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using Dev=
iceList =3D std::vector&lt;Device&gt;;<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 // 1. If it is called by reference type prefer this overload function<b=
r>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Device mergeDeviceInfo(const Device &amp; =
_first, const Device &amp; _second) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 ... // Implementation<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 2. If it is called by pointer type prefer th=
is overload function<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Device mergeDeviceIn=
fo(const Device * _firstPtr, const Device * _secondPtr) {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Implementation<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 int main()=
 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::DeviceList deviceList;<=
br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some work<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 auto founFirstDeviceIter =3D std::find_if(deviceList.begin(<div><=
wbr>), deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 ... // Some first creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto foundSecondDeviceIter =3D std::find_if(dev=
iceList.begin(<wbr>), deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 ... // Some second creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (deviceList.end() !=3D foun=
dDeviceIter0 &amp;&amp; deviceList.end() !=3D foundDeviceIter1) {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 DeviceManager::Device &amp; firstFoundDevice =3D *founFirstDevice=
Iter;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device &=
amp; secondFoundDevice =3D *foundSecondDeviceIter;</div><div><br></div><div=
>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <i>// Extension method example =
1: Overload function for references if called<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 // ADL will search in dependent scopes also for calling =
functions by object reference</i></div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 DeviceManager::Device mergedDevice =3D<b> firstFoundDevice.</b=
><wbr><b>mergeDeviceInfo(</b><wbr><b>secondFoundDevice); </b><b>// Extensio=
n method instead of </b><b>DeviceManager::</b><b>mergeDeviceInfo(</b><b>fir=
stFoundDevice</b><b><b>,</b></b><b> secondFoundDevice</b><b>)</b><br><br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <i>// Extension method example 2=
: Overload function for pointers if called<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 // ADL will search in dependent scopes lso for calling func=
tions by object pointer</i><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 D=
eviceManager::Device mergedDevice =3D <b>founFirstDeviceIter-&gt;</b><wbr><=
b>mergeDeviceInfo(*</b><wbr><b>foundDeviceIter1); // </b><b><b>Extension me=
thod instead of</b> </b><b>DeviceManager::</b><b>mergeDeviceInfo(</b><b><b>=
founFirstDeviceIter, </b></b><b>foundDeviceIter1</b><b>)</b></div><div><br>=
</div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some other wor=
k</div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }</div><=
/div><div><br></div><div> What do you think ?</div><div><br></div>=D0=B2=D1=
=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 9 =D0=BE=D0=BA=D1=82=D1=8F=D0=B1=D1=80=
=D1=8F 2018 =D0=B3., 23:28:42 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=
=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Richard Smith =D0=BD=D0=B0=D0=BF=D0=B8=D1=
=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r"><div dir=3D"ltr"><div dir=3D"ltr"><div class=3D"gmail_quote"><div dir=3D=
"ltr">On Tue, 9 Oct 2018 at 11:11, Denis Kotov &lt;<a href=3D"javascript:" =
target=3D"_blank" gdf-obfuscated-mailto=3D"zRGC4dWWAgAJ" rel=3D"nofollow" o=
nmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"th=
is.href=3D&#39;javascript:&#39;;return true;">redr...@gmail.com</a>&gt; wro=
te:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px =
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"=
ltr"><div>Hello everyone,</div><div><br></div><div>I have prepared the prop=
osal for extending an ADL search algorithm:</div><div><br></div><div><b>Pro=
pousal for extension methods like.</b> Lets consider the following example:=
</div><div><br></div><div>=C2=A0=C2=A0=C2=A0 namespace DeviceManager {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class Device {<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 ... // Other member functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t getId() const {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return id_;<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 private:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 ... // Other member variables<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };=
<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using DeviceList =3D std::vector&amp=
;lt;Device&amp;gt;;<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Device mergeDevic=
eInfo(const Device &amp; _first, const Device &amp; _second) {<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Implementation<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 int mai=
n() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::DeviceList deviceLis=
t;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some work<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 auto foundDeviceIter0 =3D std::find_if(deviceList.begin(<wbr>)=
, deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .=
... // Some first creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 auto foundDeviceIter1 =3D std::find_if(deviceList.=
begin(<wbr>), deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 ... // Some second creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
});<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (deviceList.end() !=3D foundDevice=
Iter0 &amp;&amp; deviceList.end() !=3D foundDeviceIter1) {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device mergedDevice =3D Devic=
eManager::<wbr>mergeDeviceInfo(*<wbr>foundDeviceIter0, *foundDeviceIter1);<=
br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some other work<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }</div><div><br></div><=
div>As you can see in case one helper function it is easy to manipulate and=
 use it, but in case of a lot of functions it would be better to support so=
me kind of extension methods:</div><div><br></div><div>namespace DeviceMana=
ger {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class Device {<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 ... // Other member functions<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t getId() const {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return id_;<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 private:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 ... // Other member variables<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using DeviceList =3D std::v=
ector&amp;lt;Device&amp;gt;;<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 1. If=
 it is called by reference type prefer this overload function<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 Device mergeDeviceInfo(const Device &amp; _first, con=
st Device &amp; _second) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ..=
.. // Implementation<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 // 2. If it is called by pointer type prefer this overload =
function<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Device mergeDeviceInfo(const Dev=
ice * _firstPtr, const Device * _secondPtr) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 ... // Implementation<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
}<br>=C2=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::DeviceList deviceList;<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 ... // Some work<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 au=
to foundDeviceIter0 =3D std::find_if(deviceList.begin(<wbr>), deviceList.en=
d(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some firs=
t creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 auto foundDeviceIter1 =3D std::find_if(deviceList.begin(<wbr>), d=
eviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... =
// Some second creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 if (deviceList.end() !=3D foundDeviceIter0 &amp;&amp;=
 deviceList.end() !=3D foundDeviceIter1) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 // 1. Overload function for references if called<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ADL will search in dependent scopes=
 also for calling functions by object reference<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 DeviceManager::Device &amp; firstFoundDevice =3D *foundD=
eviceIter0;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::De=
vice &amp; secondFoundDevice =3D *foundDeviceIter1;<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device mergedDevice =3D firstFoundD=
evice.<wbr>mergeDeviceInfo(<wbr>secondFoundDevice);<br><br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 2. Overload function for pointers if called<=
br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ADL will search in depende=
nt scopes lso for calling functions by object pointer<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device mergedDevice =3D foundDevice=
Iter0-&gt;<wbr>mergeDeviceInfo(*<wbr>foundDeviceIter1);<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some other work<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }</div><div><br></div><div><b>Propousal f=
or extension of ADL on template parameter.</b> Lets consider the following =
example:</div><div><br></div><div>=C2=A0=C2=A0=C2=A0 namespace IPCBus {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class IClient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 ... // Other member functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 template &amp;lt;typename TClient&amp;gt;<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static std::shared_ptr&=
amp;lt;IClient&amp;gt; buildClient() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto client =3D std::shared_ptr(new TClie=
nt);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
.... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE SKIPED !!<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return client;=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 protected:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 Client() =3D default;<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 };<br>=C2=A0=C2=A0=C2=A0 }=C2=A0 // namespace IPCBus<br><br>=C2=
=A0=C2=A0=C2=A0 class RealClient : public IClient {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 RealClient()<b=
r>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 : IClient() {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=
=A0=C2=A0 using namespace std;<br><br>=C2=A0=C2=A0=C2=A0 int main() {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto realClient =3D make_shared&amp;lt;RealC=
lient&amp;gt;(<wbr>);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // WE MISSED THE VE=
RY IMPORTANT STEPS IN CREATION OF OBJECT !!<br></div></div></blockquote><di=
v><br></div><div>If you don&#39;t want RealClient instances to be created b=
y calling the default constructor, the default constructor should not be pu=
blic. There are other techniques you can use to allow IClient to create ins=
tances of RealClient without exposing a public default constructor that cre=
ates a broken object. Your approach doesn&#39;t stop someone from doing thi=
s:</div><div><br></div><div>=C2=A0 make_unique&lt;RealClient&gt;() // still=
 broken</div><div><br></div><div>or this:</div><div><br></div><div>=C2=A0 s=
td::make_shared&lt;RealClient&gt;() // still broken</div><div><br></div><di=
v>It&#39;s also broken by the intent of P0551R3 (adopted for C++20), which =
intends to make it possible to implement standard library functions as func=
tion objects instead of as real functions, and by P0921R2, which says that =
you can&#39;t rely on (for instance) how a standard-library function will p=
artially order with respect to a function of your own.</div><div><br></div>=
<div>So I don&#39;t think this approach really solves the problem you&#39;r=
e trying to address, especially not when used to subvert calls to standard =
library functions.</div><div><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex"><div dir=3D"ltr"><div>=C2=A0=C2=A0=C2=A0 }</div><div><br></di=
v><div>As you can see in case one helper function it is easy to manipulate =
and use it, but in case of a lot of functions it would be better to support=
 some kind of extension methods:</div><div><br></div><div>=C2=A0=C2=A0=C2=
=A0 namespace IPCBus {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class IClient {<br=
>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other member functions<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 template &amp;lt;typena=
me TClient&amp;gt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 static std::shared_ptr&amp;lt;IClient&amp;gt; buildClient() {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto client =
=3D std::shared_ptr(new TClient);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // IMPORTANT THINGS AFTER INITIALIZATION=
.. CANNOT BE SKIPED !!<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 return client;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 protecte=
d:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Client() =3D d=
efault;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 template &amp;lt;typename T, typename ... TArgs&amp;gt;<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 std::shared_ptr&amp;lt;T&amp;gt; make_shared(TArgs=
&amp;&amp;... _args) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return=
 IClient::buildClient(std::<wbr>forward&amp;lt;TArgs&amp;gt;(_args)...<wbr>=
);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br></div></div></blockquote><div><br=
></div><div>This, if in scope, would likely be ambiguous with std::make_sha=
red. And if you make it a better overload candidate, it would hijack all ma=
ke_shared calls that should invoke std::make_shared. Adding an overload to =
someone else&#39;s overload set, when they didn&#39;t design for their over=
load set to be extensible, is a very bad design practice.</div><div>=C2=A0<=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bo=
rder-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><di=
v>=C2=A0=C2=A0=C2=A0 }=C2=A0 // namespace IPCBus<br><br>=C2=A0=C2=A0=C2=A0 =
class RealClient : public IClient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 publi=
c:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 RealClient()<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 : IClient() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0 using nam=
espace std;<br><br>=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 auto realClient =3D make_shared&amp;lt;RealClient&amp;gt;(<wbr>);=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // We use our own version of make_shared=
 that is delegate creation of object to builder method<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 // Cool !!<br>=C2=A0=C2=A0=C2=A0 }</div><div><br></div><div=
>As <b>Herb Sutter</b> said at <b>CppCon 2017: Herb Sutter =E2=80=9CMeta: T=
houghts on generative C++=E2=80=9D</b>:<br>&quot;Abstraction are hiders by =
definition. If they did not do this they are useless ...&quot;<br>&quot;It&=
#39;s not the problem. It is the point.&quot;<br><br>I see this suggestion =
to extend <b>ADL</b> search on caller object and on template parameter as s=
implifier for Library Writters and also General Programmers</div></div></bl=
ockquote><div><br></div><div>I don&#39;t agree at all with your motivation,=
 but nonetheless I do agree with your conclusion: it does seem reasonable f=
or ADL to consider associated classes and namespaces of template arguments =
in the case where the function name is a template-id. I suspect this was no=
t done previously because the callee in a function call for which ADL is pe=
rformed was very rarely a template-id prior to P0846R0, but now we&#39;ve a=
dopted that paper for C++20, it would make sense to take the associated cla=
sses and namespaces of the template arguments into account, and especially =
because we now allow objects of class type as non-type template arguments:<=
/div><div><br></div><div>namespace N {</div><div>=C2=A0 struct Params { /*.=
...*/ };</div><div>=C2=A0 auto make_dynamic(Params P) { /*...*/ }<br></div><=
div>=C2=A0 template&lt;Params P&gt; auto make_static() { /*...*/ }</div><di=
v>}<br></div><div>auto x =3D make_dynamic(N::Params{1, 2, 3}); // OK</div><=
div>auto y =3D make_static&lt;N::Params{1, 2, 3}&gt;(); // error today, cou=
ld be valid tomorrow</div></div></div></div></div>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9579b759-d5c0-41c9-a224-5c54fcf88274%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9579b759-d5c0-41c9-a224-5c54fcf88274=
%40isocpp.org</a>.<br />

------=_Part_2504_973252305.1539155513559--

------=_Part_2503_278951322.1539155513558--

.


Author: Denis Kotov <redradist@gmail.com>
Date: Wed, 10 Oct 2018 08:10:13 -0700 (PDT)
Raw View
------=_Part_2787_1050489960.1539184213419
Content-Type: multipart/alternative;
 boundary="----=_Part_2788_1412570755.1539184213419"

------=_Part_2788_1412570755.1539184213419
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Thank you Ga=C5=A1per,

I will use it

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 9 =D0=BE=D0=BA=D1=82=D1=8F=D0=
=B1=D1=80=D1=8F 2018 =D0=B3., 23:31:26 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=
=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Ga=C5=A1per A=C5=BEman=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> Hi Denis,
>
> You might want to include a link to a rendered version of the HTML on you=
r=20
> github. I would also suggest using bikeshed (=20
> https://github.com/tabatkins/bikeshed ) to write it, as you will get=20
> automatic code highlighting and help with specifying the various needed=
=20
> sections. This will make it easier for everyone to read your proposal.
>
> As an example, here is a published one:
> https://atomgalaxy.github.io/brevzin-wg21/0847_deducing_this/p0847r1.html
> The source is here (enable github sites to get it to display properly):=
=20
> https://github.com/atomgalaxy/brevzin-wg21/tree/master/0847_deducing_this
>
> Everyone will thank you :).
>
> Ga=C5=A1per
>
> On Tue, Oct 9, 2018 at 7:16 PM Denis Kotov <redr...@gmail.com=20
> <javascript:>> wrote:
>
>> This proposal is available on GitHub also=20
>> https://github.com/redradist/cpp_standard_propousals/blob/master/ADL%20E=
xtension.html=20
>>
>> =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 9 =D0=BE=D0=BA=D1=82=D1=8F=
=D0=B1=D1=80=D1=8F 2018 =D0=B3., 21:11:13 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=
=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Denis Kotov=20
>> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>>
>>> Hello everyone,
>>>
>>> I have prepared the proposal for extending an ADL search algorithm:
>>>
>>> *Propousal for extension methods like.* Lets consider the following=20
>>> example:
>>>
>>>     namespace DeviceManager {
>>>       class Device {
>>>         public:
>>>           ... // Other member functions
>>>           uint32_t getId() const {
>>>             return id_;
>>>           }
>>>         private:
>>>           ... // Other member variables
>>>           uint32_t id_;
>>>       };
>>>
>>>       using DeviceList =3D std::vector&lt;Device&gt;;
>>>
>>>       Device mergeDeviceInfo(const Device & _first, const Device &=20
>>> _second) {
>>>         ... // Implementation
>>>       }
>>>     }
>>>
>>>     int main() {
>>>       DeviceManager::DeviceList deviceList;
>>>       ... // Some work
>>>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),=20
>>> deviceList.end(), [=3D] {
>>>         ... // Some first creteria
>>>       });
>>>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),=20
>>> deviceList.end(), [=3D] {
>>>         ... // Some second creteria
>>>       });
>>>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=
=3D=20
>>> foundDeviceIter1) {
>>>         DeviceManager::Device mergedDevice =3D=20
>>> DeviceManager::mergeDeviceInfo(*foundDeviceIter0, *foundDeviceIter1);
>>>         ... // Some other work
>>>       }
>>>     }
>>>
>>> As you can see in case one helper function it is easy to manipulate and=
=20
>>> use it, but in case of a lot of functions it would be better to support=
=20
>>> some kind of extension methods:
>>>
>>> namespace DeviceManager {
>>>       class Device {
>>>         public:
>>>           ... // Other member functions
>>>           uint32_t getId() const {
>>>             return id_;
>>>           }
>>>         private:
>>>           ... // Other member variables
>>>           uint32_t id_;
>>>       };
>>>
>>>       using DeviceList =3D std::vector&lt;Device&gt;;
>>>
>>>       // 1. If it is called by reference type prefer this overload=20
>>> function
>>>       Device mergeDeviceInfo(const Device & _first, const Device &=20
>>> _second) {
>>>         ... // Implementation
>>>       }
>>>       // 2. If it is called by pointer type prefer this overload functi=
on
>>>       Device mergeDeviceInfo(const Device * _firstPtr, const Device *=
=20
>>> _secondPtr) {
>>>         ... // Implementation
>>>       }
>>>     }
>>>
>>>     int main() {
>>>       DeviceManager::DeviceList deviceList;
>>>       ... // Some work
>>>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),=20
>>> deviceList.end(), [=3D] {
>>>         ... // Some first creteria
>>>       });
>>>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),=20
>>> deviceList.end(), [=3D] {
>>>         ... // Some second creteria
>>>       });
>>>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=
=3D=20
>>> foundDeviceIter1) {
>>>         // 1. Overload function for references if called
>>>         // ADL will search in dependent scopes also for calling=20
>>> functions by object reference
>>>         DeviceManager::Device & firstFoundDevice =3D *foundDeviceIter0;
>>>         DeviceManager::Device & secondFoundDevice =3D *foundDeviceIter1=
;
>>>         DeviceManager::Device mergedDevice =3D=20
>>> firstFoundDevice.mergeDeviceInfo(secondFoundDevice);
>>>
>>>         // 2. Overload function for pointers if called
>>>         // ADL will search in dependent scopes lso for calling function=
s=20
>>> by object pointer
>>>         DeviceManager::Device mergedDevice =3D=20
>>> foundDeviceIter0->mergeDeviceInfo(*foundDeviceIter1);
>>>         ... // Some other work
>>>       }
>>>     }
>>>
>>> *Propousal for extension of ADL on template parameter.* Lets consider=
=20
>>> the following example:
>>>
>>>     namespace IPCBus {
>>>       class IClient {
>>>         public:
>>>           ... // Other member functions
>>>           template &lt;typename TClient&gt;
>>>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>>>             auto client =3D std::shared_ptr(new TClient);
>>>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE=20
>>> SKIPED !!
>>>             return client;
>>>           }
>>>         protected:
>>>           Client() =3D default;
>>>       };
>>>     }  // namespace IPCBus
>>>
>>>     class RealClient : public IClient {
>>>       public:
>>>        RealClient()
>>>          : IClient() {
>>>        }
>>>     };
>>>
>>>     using namespace std;
>>>
>>>     int main() {
>>>       auto realClient =3D make_shared&lt;RealClient&gt;();
>>>       // WE MISSED THE VERY IMPORTANT STEPS IN CREATION OF OBJECT !!
>>>     }
>>>
>>> As you can see in case one helper function it is easy to manipulate and=
=20
>>> use it, but in case of a lot of functions it would be better to support=
=20
>>> some kind of extension methods:
>>>
>>>     namespace IPCBus {
>>>       class IClient {
>>>         public:
>>>           ... // Other member functions
>>>           template &lt;typename TClient&gt;
>>>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>>>             auto client =3D std::shared_ptr(new TClient);
>>>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE=20
>>> SKIPED !!
>>>             return client;
>>>           }
>>>         protected:
>>>           Client() =3D default;
>>>       };
>>>
>>>       template &lt;typename T, typename ... TArgs&gt;
>>>       std::shared_ptr&lt;T&gt; make_shared(TArgs&&... _args) {
>>>         return IClient::buildClient(std::forward&lt;TArgs&gt;(_args)...=
);
>>>       }
>>>     }  // namespace IPCBus
>>>
>>>     class RealClient : public IClient {
>>>       public:
>>>        RealClient()
>>>          : IClient() {
>>>        }
>>>     };
>>>
>>>     using namespace std;
>>>
>>>     int main() {
>>>       auto realClient =3D make_shared&lt;RealClient&gt;();
>>>       // We use our own version of make_shared that is delegate creatio=
n=20
>>> of object to builder method
>>>       // Cool !!
>>>     }
>>>
>>> As *Herb Sutter* said at *CppCon 2017: Herb Sutter =E2=80=9CMeta: Thoug=
hts on=20
>>> generative C++=E2=80=9D*:
>>> "Abstraction are hiders by definition. If they did not do this they are=
=20
>>> useless ..."
>>> "It's not the problem. It is the point."
>>>
>>> I see this suggestion to extend *ADL* search on caller object and on=20
>>> template parameter as simplifier for Library Writters and also General=
=20
>>> Programmers
>>>
>> --=20
>> You received this message because you are subscribed to the Google Group=
s=20
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n=20
>> email to std-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit=20
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cf51a959-42=
d4-42c5-9e25-1455681402ff%40isocpp.org=20
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cf51a959-4=
2d4-42c5-9e25-1455681402ff%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoo=
ter>
>> .
>>
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/4782ecca-e1e8-4c0d-bc5b-7d769fb79387%40isocpp.or=
g.

------=_Part_2788_1412570755.1539184213419
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Thank you Ga=C5=A1per,</div><div><br></div><div>I wil=
l use it<br></div><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 9 =D0=BE=
=D0=BA=D1=82=D1=8F=D0=B1=D1=80=D1=8F 2018 =D0=B3., 23:31:26 UTC+3 =D0=BF=D0=
=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Ga=C5=A1per=
 A=C5=BEman =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"=
><div dir=3D"ltr">Hi Denis,<div><br></div><div>You might want to include a =
link to a rendered version of the HTML on your github. I would also suggest=
 using bikeshed ( <a href=3D"https://github.com/tabatkins/bikeshed" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.go=
ogle.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Ftabatkins%2Fbikeshed\x26sa\x3d=
D\x26sntz\x3d1\x26usg\x3dAFQjCNH69cQJ4slRKHYlWElAZxIqBUuC1Q&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F=
%2Fgithub.com%2Ftabatkins%2Fbikeshed\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQj=
CNH69cQJ4slRKHYlWElAZxIqBUuC1Q&#39;;return true;">https://github.com/tabatk=
ins/<wbr>bikeshed</a> ) to write it, as you will get automatic code highlig=
hting and help with specifying the various needed sections. This will make =
it easier for everyone to read your proposal.</div><div><br></div><div>As a=
n example, here is a published one:</div><div><a href=3D"https://atomgalaxy=
..github.io/brevzin-wg21/0847_deducing_this/p0847r1.html" target=3D"_blank" =
rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.google.com/url=
?q\x3dhttps%3A%2F%2Fatomgalaxy.github.io%2Fbrevzin-wg21%2F0847_deducing_thi=
s%2Fp0847r1.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFiTiR7t4DBnvxNdneK=
bqX7N8w6zQ&#39;;return true;" onclick=3D"this.href=3D&#39;https://www.googl=
e.com/url?q\x3dhttps%3A%2F%2Fatomgalaxy.github.io%2Fbrevzin-wg21%2F0847_ded=
ucing_this%2Fp0847r1.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFiTiR7t4D=
BnvxNdneKbqX7N8w6zQ&#39;;return true;">https://atomgalaxy.github.io/<wbr>br=
evzin-wg21/0847_deducing_<wbr>this/p0847r1.html</a></div><div>The source is=
 here (enable github sites to get it to display properly):=C2=A0<a href=3D"=
https://github.com/atomgalaxy/brevzin-wg21/tree/master/0847_deducing_this" =
target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://=
www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fatomgalaxy%2Fbrevzin-wg2=
1%2Ftree%2Fmaster%2F0847_deducing_this\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAF=
QjCNG8g1rMaUQB9UyMeWspJsiZ0dloPg&#39;;return true;" onclick=3D"this.href=3D=
&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fatomgalaxy%=
2Fbrevzin-wg21%2Ftree%2Fmaster%2F0847_deducing_this\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNG8g1rMaUQB9UyMeWspJsiZ0dloPg&#39;;return true;">https://gi=
thub.com/<wbr>atomgalaxy/brevzin-wg21/tree/<wbr>master/0847_deducing_this</=
a></div><div><br></div><div>Everyone will thank you :).</div><div><br></div=
><div>Ga=C5=A1per</div></div></div></div></div><br><div class=3D"gmail_quot=
e"><div dir=3D"ltr">On Tue, Oct 9, 2018 at 7:16 PM Denis Kotov &lt;<a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"55Vu8vuWAgAJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">redr...@gmai=
l.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r">This proposal is available on GitHub also <a href=3D"https://github.com/=
redradist/cpp_standard_propousals/blob/master/ADL%20Extension.html" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.go=
ogle.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fredradist%2Fcpp_standard_propo=
usals%2Fblob%2Fmaster%2FADL%2520Extension.html\x26sa\x3dD\x26sntz\x3d1\x26u=
sg\x3dAFQjCNGZ348JM4Uq2KiUFey6QC5dNhCR2A&#39;;return true;" onclick=3D"this=
..href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fred=
radist%2Fcpp_standard_propousals%2Fblob%2Fmaster%2FADL%2520Extension.html\x=
26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGZ348JM4Uq2KiUFey6QC5dNhCR2A&#39;;re=
turn true;">https://github.com/redradist/<wbr>cpp_standard_propousals/blob/=
<wbr>master/ADL%20Extension.html</a> <br><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=
=D0=B8=D0=BA, 9 =D0=BE=D0=BA=D1=82=D1=8F=D0=B1=D1=80=D1=8F 2018 =D0=B3., 21=
:11:13 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=
=D0=BB=D1=8C Denis Kotov =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Hello everyone,</div=
><div><br></div><div>I have prepared the proposal for extending an ADL sear=
ch algorithm:</div><div><br></div><div><b>Propousal for extension methods l=
ike.</b> Lets consider the following example:</div><div><br></div><div>=C2=
=A0=C2=A0=C2=A0 namespace DeviceManager {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 class Device {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other member =
functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_=
t getId() const {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 return id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 private:<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other member var=
iables<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t i=
d_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 using DeviceList =3D std::vector&amp;lt;Device&amp;gt;;<br><br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 Device mergeDeviceInfo(const Device &amp; _first, =
const Device &amp; _second) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 ... // Implementation<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=
=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 DeviceManager::DeviceList deviceList;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 ... // Some work<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto foundDeviceIter=
0 =3D std::find_if(deviceList.begin(<wbr>), deviceList.end(), [=3D] {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some first creteria<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto f=
oundDeviceIter1 =3D std::find_if(deviceList.begin(<wbr>), deviceList.end(),=
 [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some second c=
reteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 if (deviceList.end() !=3D foundDeviceIter0 &amp;&amp; deviceList.end=
() !=3D foundDeviceIter1) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 D=
eviceManager::Device mergedDevice =3D DeviceManager::<wbr>mergeDeviceInfo(*=
<wbr>foundDeviceIter0, *foundDeviceIter1);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 ... // Some other work<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<=
br>=C2=A0=C2=A0=C2=A0 }</div><div><br></div><div>As you can see in case one=
 helper function it is easy to manipulate and use it, but in case of a lot =
of functions it would be better to support some kind of extension methods:<=
/div><div><br></div><div>namespace DeviceManager {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 class Device {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 publ=
ic:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other =
member functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
uint32_t getId() const {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 return id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 private:=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other mem=
ber variables<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uin=
t32_t id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 using DeviceList =3D std::vector&amp;lt;Device&amp;gt;;<br><br=
>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 1. If it is called by reference type pre=
fer this overload function<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Device mergeDe=
viceInfo(const Device &amp; _first, const Device &amp; _second) {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Implementation<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 2. If it is calle=
d by pointer type prefer this overload function<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 Device mergeDeviceInfo(const Device * _firstPtr, const Device * _sec=
ondPtr) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Implementati=
on<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }<br><br>=C2=
=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManage=
r::DeviceList deviceList;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some wor=
k<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto foundDeviceIter0 =3D std::find_if(=
deviceList.begin(<wbr>), deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 ... // Some first creteria<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto foundDeviceIter1 =3D s=
td::find_if(deviceList.begin(<wbr>), deviceList.end(), [=3D] {<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some second creteria<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (deviceList.=
end() !=3D foundDeviceIter0 &amp;&amp; deviceList.end() !=3D foundDeviceIte=
r1) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 1. Overload function=
 for references if called<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // =
ADL will search in dependent scopes also for calling functions by object re=
ference<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device=
 &amp; firstFoundDevice =3D *foundDeviceIter0;<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 DeviceManager::Device &amp; secondFoundDevice =3D *found=
DeviceIter1;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::D=
evice mergedDevice =3D firstFoundDevice.<wbr>mergeDeviceInfo(<wbr>secondFou=
ndDevice);<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 2. Overload=
 function for pointers if called<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 // ADL will search in dependent scopes lso for calling functions by obj=
ect pointer<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::De=
vice mergedDevice =3D foundDeviceIter0-&gt;<wbr>mergeDeviceInfo(*<wbr>found=
DeviceIter1);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some oth=
er work<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }</div><d=
iv><br></div><div><b>Propousal for extension of ADL on template parameter.<=
/b> Lets consider the following example:</div><div><br></div><div>=C2=A0=C2=
=A0=C2=A0 namespace IPCBus {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class IClien=
t {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other member functions<br=
>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 template &amp;lt;ty=
pename TClient&amp;gt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 static std::shared_ptr&amp;lt;IClient&amp;gt; buildClient() {<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto client=
 =3D std::shared_ptr(new TClient);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // IMPORTANT THINGS AFTER INITIALIZATION=
.. CANNOT BE SKIPED !!<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 return client;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 protecte=
d:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Client() =3D d=
efault;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br>=C2=A0=C2=A0=C2=A0 }=C2=A0 =
// namespace IPCBus<br><br>=C2=A0=C2=A0=C2=A0 class RealClient : public ICl=
ient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 RealClient()<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 : IClient() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=
=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0 using namespace std;<br><br>=C2=A0=
=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto realClient=
 =3D make_shared&amp;lt;RealClient&amp;gt;(<wbr>);<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 // WE MISSED THE VERY IMPORTANT STEPS IN CREATION OF OBJECT !!<br=
>=C2=A0=C2=A0=C2=A0 }</div><div><br></div><div>As you can see in case one h=
elper function it is easy to manipulate and use it, but in case of a lot of=
 functions it would be better to support some kind of extension methods:</d=
iv><div><br></div><div>=C2=A0=C2=A0=C2=A0 namespace IPCBus {<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 class IClient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 ... // Other member functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 template &amp;lt;typename TClient&amp;gt;<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static std::shared_ptr&amp;lt;IC=
lient&amp;gt; buildClient() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 auto client =3D std::shared_ptr(new TClient);<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // I=
MPORTANT THINGS AFTER INITIALIZATION. CANNOT BE SKIPED !!<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return client;<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 protected:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 Client() =3D default;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 };<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 template &amp;lt;typename T, t=
ypename ... TArgs&amp;gt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 std::shared_ptr=
&amp;lt;T&amp;gt; make_shared(TArgs&amp;&amp;... _args) {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return IClient::buildClient(std::<wbr>forwar=
d&amp;lt;TArgs&amp;gt;(_args)...<wbr>);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }=
<br>=C2=A0=C2=A0=C2=A0 }=C2=A0 // namespace IPCBus<br><br>=C2=A0=C2=A0=C2=
=A0 class RealClient : public IClient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 p=
ublic:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 RealClient()<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 : IClient() {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0 using =
namespace std;<br><br>=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 auto realClient =3D make_shared&amp;lt;RealClient&amp;gt;(<wbr=
>);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // We use our own version of make_sha=
red that is delegate creation of object to builder method<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 // Cool !!<br>=C2=A0=C2=A0=C2=A0 }</div><div><br></div><=
div>As <b>Herb Sutter</b> said at <b>CppCon 2017: Herb Sutter =E2=80=9CMeta=
: Thoughts on generative C++=E2=80=9D</b>:<br>&quot;Abstraction are hiders =
by definition. If they did not do this they are useless ...&quot;<br>&quot;=
It&#39;s not the problem. It is the point.&quot;<br><br>I see this suggesti=
on to extend <b>ADL</b> search on caller object and on template parameter a=
s simplifier for Library Writters and also General Programmers<br></div></d=
iv></blockquote></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
55Vu8vuWAgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&=
#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"55Vu8vuWAgAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39=
;javascript:&#39;;return true;">std-pr...@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/cf51a959-42d4-42c5-9e25-1455681402ff%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank" =
rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/cf51a959-42d4-42c5-9e25-1455681402ff%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" on=
click=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/cf51a959-42d4-42c5-9e25-1455681402ff%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/cf51a959-42d4-42c5-<wbr>9e25-=
1455681402ff%40isocpp.org</a><wbr>.<br>
</blockquote></div>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4782ecca-e1e8-4c0d-bc5b-7d769fb79387%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/4782ecca-e1e8-4c0d-bc5b-7d769fb79387=
%40isocpp.org</a>.<br />

------=_Part_2788_1412570755.1539184213419--

------=_Part_2787_1050489960.1539184213419--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Wed, 10 Oct 2018 13:40:01 -0700
Raw View
--0000000000007a18230577e5dc24
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, 10 Oct 2018 at 00:11, Denis Kotov <redradist@gmail.com> wrote:

> Hello Richard,
>
> With make_shared it was just an example, but nonetheless I wanted to make
> *ADL* look-up on template parameter dependent scope just for more
> flexibility for developer
> I appreciate that you like the idea for searching on template parameter
>
> What about my* first proposal* ? About extension methods:
>
>     namespace DeviceManager {
>       class Device {
>         public:
>           ... // Other member functions
>           uint32_t getId() const {
>             return id_;
>           }
>         private:
>           ... // Other member variables
>           uint32_t id_;
>       };
>
>       using DeviceList =3D std::vector<Device>;
>
>       // 1. If it is called by reference type prefer this overload functi=
on
>       Device mergeDeviceInfo(const Device & _first, const Device &
> _second) {
>         ... // Implementation
>       }
>       // 2. If it is called by pointer type prefer this overload function
>       Device mergeDeviceInfo(const Device * _firstPtr, const Device *
> _secondPtr) {
>         ... // Implementation
>       }
>     }
>
>     int main() {
>       DeviceManager::DeviceList deviceList;
>       ... // Some work
>       auto founFirstDeviceIter =3D std::find_if(deviceList.begin(
> ), deviceList.end(), [=3D] {
>         ... // Some first creteria
>       });
>       auto foundSecondDeviceIter =3D std::find_if(deviceList.begin(),
> deviceList.end(), [=3D] {
>         ... // Some second creteria
>       });
>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=3D
> foundDeviceIter1) {
>
>         DeviceManager::Device & firstFoundDevice =3D *founFirstDeviceIter=
;
>         DeviceManager::Device & secondFoundDevice =3D *foundSecondDeviceI=
ter;
>
>
> *// Extension method example 1: Overload function for references if
> called        // ADL will search in dependent scopes also for calling
> functions by object reference*
>         DeviceManager::Device mergedDevice =3D* firstFoundDevice.*
> *mergeDeviceInfo(**secondFoundDevice); **// Extension method instead of *
> *DeviceManager::**mergeDeviceInfo(**firstFoundDevice**,**
> secondFoundDevice**)*
>
>
> *// Extension method example 2: Overload function for pointers if
> called        // ADL will search in dependent scopes lso for calling
> functions by object pointer*
>         DeviceManager::Device mergedDevice =3D *founFirstDeviceIter->*
> *mergeDeviceInfo(***foundDeviceIter1); // **Extension method instead of *
> *DeviceManager::**mergeDeviceInfo(**founFirstDeviceIter, *
> *foundDeviceIter1**)*
>
>         ... // Some other work
>       }
>     }
>
> What do you think ?
>

Something very similar to this has already been proposed as part of unified
function call syntax (n4474), and the C++ committee rejected it. I don't
think it will be reconsidered unless you have substantial new arguments /
evidence for it, or a new design that avoids the problems with the previous
approach.


> =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 9 =D0=BE=D0=BA=D1=82=D1=8F=D0=
=B1=D1=80=D1=8F 2018 =D0=B3., 23:28:42 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=
=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Richard Smith
> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>
>> On Tue, 9 Oct 2018 at 11:11, Denis Kotov <redr...@gmail.com> wrote:
>>
>>> Hello everyone,
>>>
>>> I have prepared the proposal for extending an ADL search algorithm:
>>>
>>> *Propousal for extension methods like.* Lets consider the following
>>> example:
>>>
>>>     namespace DeviceManager {
>>>       class Device {
>>>         public:
>>>           ... // Other member functions
>>>           uint32_t getId() const {
>>>             return id_;
>>>           }
>>>         private:
>>>           ... // Other member variables
>>>           uint32_t id_;
>>>       };
>>>
>>>       using DeviceList =3D std::vector&lt;Device&gt;;
>>>
>>>       Device mergeDeviceInfo(const Device & _first, const Device &
>>> _second) {
>>>         ... // Implementation
>>>       }
>>>     }
>>>
>>>     int main() {
>>>       DeviceManager::DeviceList deviceList;
>>>       ... // Some work
>>>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),
>>> deviceList.end(), [=3D] {
>>>         ... // Some first creteria
>>>       });
>>>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),
>>> deviceList.end(), [=3D] {
>>>         ... // Some second creteria
>>>       });
>>>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=
=3D
>>> foundDeviceIter1) {
>>>         DeviceManager::Device mergedDevice =3D
>>> DeviceManager::mergeDeviceInfo(*foundDeviceIter0, *foundDeviceIter1);
>>>         ... // Some other work
>>>       }
>>>     }
>>>
>>> As you can see in case one helper function it is easy to manipulate and
>>> use it, but in case of a lot of functions it would be better to support
>>> some kind of extension methods:
>>>
>>> namespace DeviceManager {
>>>       class Device {
>>>         public:
>>>           ... // Other member functions
>>>           uint32_t getId() const {
>>>             return id_;
>>>           }
>>>         private:
>>>           ... // Other member variables
>>>           uint32_t id_;
>>>       };
>>>
>>>       using DeviceList =3D std::vector&lt;Device&gt;;
>>>
>>>       // 1. If it is called by reference type prefer this overload
>>> function
>>>       Device mergeDeviceInfo(const Device & _first, const Device &
>>> _second) {
>>>         ... // Implementation
>>>       }
>>>       // 2. If it is called by pointer type prefer this overload functi=
on
>>>       Device mergeDeviceInfo(const Device * _firstPtr, const Device *
>>> _secondPtr) {
>>>         ... // Implementation
>>>       }
>>>     }
>>>
>>>     int main() {
>>>       DeviceManager::DeviceList deviceList;
>>>       ... // Some work
>>>       auto foundDeviceIter0 =3D std::find_if(deviceList.begin(),
>>> deviceList.end(), [=3D] {
>>>         ... // Some first creteria
>>>       });
>>>       auto foundDeviceIter1 =3D std::find_if(deviceList.begin(),
>>> deviceList.end(), [=3D] {
>>>         ... // Some second creteria
>>>       });
>>>       if (deviceList.end() !=3D foundDeviceIter0 && deviceList.end() !=
=3D
>>> foundDeviceIter1) {
>>>         // 1. Overload function for references if called
>>>         // ADL will search in dependent scopes also for calling
>>> functions by object reference
>>>         DeviceManager::Device & firstFoundDevice =3D *foundDeviceIter0;
>>>         DeviceManager::Device & secondFoundDevice =3D *foundDeviceIter1=
;
>>>         DeviceManager::Device mergedDevice =3D
>>> firstFoundDevice.mergeDeviceInfo(secondFoundDevice);
>>>
>>>         // 2. Overload function for pointers if called
>>>         // ADL will search in dependent scopes lso for calling function=
s
>>> by object pointer
>>>         DeviceManager::Device mergedDevice =3D
>>> foundDeviceIter0->mergeDeviceInfo(*foundDeviceIter1);
>>>         ... // Some other work
>>>       }
>>>     }
>>>
>>> *Propousal for extension of ADL on template parameter.* Lets consider
>>> the following example:
>>>
>>>     namespace IPCBus {
>>>       class IClient {
>>>         public:
>>>           ... // Other member functions
>>>           template &lt;typename TClient&gt;
>>>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>>>             auto client =3D std::shared_ptr(new TClient);
>>>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE
>>> SKIPED !!
>>>             return client;
>>>           }
>>>         protected:
>>>           Client() =3D default;
>>>       };
>>>     }  // namespace IPCBus
>>>
>>>     class RealClient : public IClient {
>>>       public:
>>>        RealClient()
>>>          : IClient() {
>>>        }
>>>     };
>>>
>>>     using namespace std;
>>>
>>>     int main() {
>>>       auto realClient =3D make_shared&lt;RealClient&gt;();
>>>       // WE MISSED THE VERY IMPORTANT STEPS IN CREATION OF OBJECT !!
>>>
>>
>> If you don't want RealClient instances to be created by calling the
>> default constructor, the default constructor should not be public. There
>> are other techniques you can use to allow IClient to create instances of
>> RealClient without exposing a public default constructor that creates a
>> broken object. Your approach doesn't stop someone from doing this:
>>
>>   make_unique<RealClient>() // still broken
>>
>> or this:
>>
>>   std::make_shared<RealClient>() // still broken
>>
>> It's also broken by the intent of P0551R3 (adopted for C++20), which
>> intends to make it possible to implement standard library functions as
>> function objects instead of as real functions, and by P0921R2, which say=
s
>> that you can't rely on (for instance) how a standard-library function wi=
ll
>> partially order with respect to a function of your own.
>>
>> So I don't think this approach really solves the problem you're trying t=
o
>> address, especially not when used to subvert calls to standard library
>> functions.
>>
>>     }
>>>
>>> As you can see in case one helper function it is easy to manipulate and
>>> use it, but in case of a lot of functions it would be better to support
>>> some kind of extension methods:
>>>
>>>     namespace IPCBus {
>>>       class IClient {
>>>         public:
>>>           ... // Other member functions
>>>           template &lt;typename TClient&gt;
>>>           static std::shared_ptr&lt;IClient&gt; buildClient() {
>>>             auto client =3D std::shared_ptr(new TClient);
>>>             ... // IMPORTANT THINGS AFTER INITIALIZATION. CANNOT BE
>>> SKIPED !!
>>>             return client;
>>>           }
>>>         protected:
>>>           Client() =3D default;
>>>       };
>>>
>>>       template &lt;typename T, typename ... TArgs&gt;
>>>       std::shared_ptr&lt;T&gt; make_shared(TArgs&&... _args) {
>>>         return IClient::buildClient(std::forward&lt;TArgs&gt;(_args)...=
);
>>>       }
>>>
>>
>> This, if in scope, would likely be ambiguous with std::make_shared. And
>> if you make it a better overload candidate, it would hijack all make_sha=
red
>> calls that should invoke std::make_shared. Adding an overload to someone
>> else's overload set, when they didn't design for their overload set to b=
e
>> extensible, is a very bad design practice.
>>
>>
>>>     }  // namespace IPCBus
>>>
>>>     class RealClient : public IClient {
>>>       public:
>>>        RealClient()
>>>          : IClient() {
>>>        }
>>>     };
>>>
>>>     using namespace std;
>>>
>>>     int main() {
>>>       auto realClient =3D make_shared&lt;RealClient&gt;();
>>>       // We use our own version of make_shared that is delegate creatio=
n
>>> of object to builder method
>>>       // Cool !!
>>>     }
>>>
>>> As *Herb Sutter* said at *CppCon 2017: Herb Sutter =E2=80=9CMeta: Thoug=
hts on
>>> generative C++=E2=80=9D*:
>>> "Abstraction are hiders by definition. If they did not do this they are
>>> useless ..."
>>> "It's not the problem. It is the point."
>>>
>>> I see this suggestion to extend *ADL* search on caller object and on
>>> template parameter as simplifier for Library Writters and also General
>>> Programmers
>>>
>>
>> I don't agree at all with your motivation, but nonetheless I do agree
>> with your conclusion: it does seem reasonable for ADL to consider
>> associated classes and namespaces of template arguments in the case wher=
e
>> the function name is a template-id. I suspect this was not done previous=
ly
>> because the callee in a function call for which ADL is performed was ver=
y
>> rarely a template-id prior to P0846R0, but now we've adopted that paper =
for
>> C++20, it would make sense to take the associated classes and namespaces=
 of
>> the template arguments into account, and especially because we now allow
>> objects of class type as non-type template arguments:
>>
>> namespace N {
>>   struct Params { /*...*/ };
>>   auto make_dynamic(Params P) { /*...*/ }
>>   template<Params P> auto make_static() { /*...*/ }
>> }
>> auto x =3D make_dynamic(N::Params{1, 2, 3}); // OK
>> auto y =3D make_static<N::Params{1, 2, 3}>(); // error today, could be
>> valid tomorrow
>>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9579b759-d5c=
0-41c9-a224-5c54fcf88274%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9579b759-d5=
c0-41c9-a224-5c54fcf88274%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAOfiQqmM44LZXC28U4A%3Dn2PV9TJCDYPf9NRaUaYX4XGEX=
Dv0Tg%40mail.gmail.com.

--0000000000007a18230577e5dc24
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><div class=3D"gmail_quote"><div dir=3D"lt=
r">On Wed, 10 Oct 2018 at 00:11, Denis Kotov &lt;<a href=3D"mailto:redradis=
t@gmail.com">redradist@gmail.com</a>&gt; wrote:<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Hello Richard,</div>=
<div><br></div><div>With make_shared it was just an example, but nonetheles=
s I wanted to make <b>ADL</b> look-up on template parameter dependent scope=
 just for more flexibility for developer</div><div>I appreciate that you li=
ke the idea for searching on template parameter<br></div><div><br></div><di=
v>What about my<b> first proposal</b> ? About extension methods:</div><div>=
<br></div><div>=C2=A0=C2=A0=C2=A0 namespace DeviceManager {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 class Device {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ..=
.. // Other member functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 uint32_t getId() const {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 private:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... =
// Other member variables<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 uint32_t id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 using DeviceList =3D std::vector&lt;Device&gt;;<br=
><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 1. If it is called by reference type=
 prefer this overload function<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Device mer=
geDeviceInfo(const Device &amp; _first, const Device &amp; _second) {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Implementation<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 2. If it is=
 called by pointer type prefer this overload function<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 Device mergeDeviceInfo(const Device * _firstPtr, const Device =
* _secondPtr) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Implem=
entation<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }<br><br=
>=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceMa=
nager::DeviceList deviceList;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some=
 work<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto founFirstDeviceIter =3D std::f=
ind_if(deviceList.begin(<div>), deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some first creteria<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto foundSecondDe=
viceIter =3D std::find_if(deviceList.begin(), deviceList.end(), [=3D] {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some second creteria<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (de=
viceList.end() !=3D foundDeviceIter0 &amp;&amp; deviceList.end() !=3D found=
DeviceIter1) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device &amp; firstFoundDev=
ice =3D *founFirstDeviceIter;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 DeviceManager::Device &amp; secondFoundDevice =3D *foundSecondDeviceIter;<=
/div><div><br></div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <i>// E=
xtension method example 1: Overload function for references if called<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ADL will search in dependent =
scopes also for calling functions by object reference</i></div><div>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device mergedDevice =3D=
<b> firstFoundDevice.</b><b>mergeDeviceInfo(</b><b>secondFoundDevice); </b>=
<b>// Extension method instead of </b><b>DeviceManager::</b><b>mergeDeviceI=
nfo(</b><b>firstFoundDevice</b><b><b>,</b></b><b> secondFoundDevice</b><b>)=
</b><br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <i>// Extension meth=
od example 2: Overload function for pointers if called<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ADL will search in dependent scopes lso for =
calling functions by object pointer</i><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 DeviceManager::Device mergedDevice =3D <b>founFirstDeviceIter-=
&gt;</b><b>mergeDeviceInfo(*</b><b>foundDeviceIter1); // </b><b><b>Extensio=
n method instead of</b> </b><b>DeviceManager::</b><b>mergeDeviceInfo(</b><b=
><b>founFirstDeviceIter, </b></b><b>foundDeviceIter1</b><b>)</b></div><div>=
<br></div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some other=
 work</div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }</d=
iv></div><div><br></div><div> What do you think ?</div></div></blockquote><=
div><br></div><div>Something very similar to this has already been proposed=
 as part of unified function call syntax (n4474), and the C++ committee rej=
ected it. I don&#39;t think it will be reconsidered unless you have substan=
tial new arguments / evidence for it, or a new design that avoids the probl=
ems with the previous approach.</div><div>=C2=A0</div><blockquote class=3D"=
gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(20=
4,204,204);padding-left:1ex"><div dir=3D"ltr">=D0=B2=D1=82=D0=BE=D1=80=D0=
=BD=D0=B8=D0=BA, 9 =D0=BE=D0=BA=D1=82=D1=8F=D0=B1=D1=80=D1=8F 2018 =D0=B3.,=
 23:28:42 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=
=B5=D0=BB=D1=8C Richard Smith =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div dir=
=3D"ltr"><div dir=3D"ltr"><div class=3D"gmail_quote"><div dir=3D"ltr">On Tu=
e, 9 Oct 2018 at 11:11, Denis Kotov &lt;<a rel=3D"nofollow">redr...@gmail.c=
om</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex=
"><div dir=3D"ltr"><div>Hello everyone,</div><div><br></div><div>I have pre=
pared the proposal for extending an ADL search algorithm:</div><div><br></d=
iv><div><b>Propousal for extension methods like.</b> Lets consider the foll=
owing example:</div><div><br></div><div>=C2=A0=C2=A0=C2=A0 namespace Device=
Manager {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class Device {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 ... // Other member functions<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t getId() const {<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return id_;<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 private:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 ... // Other member variables<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t id_;<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using DeviceList =3D std=
::vector&amp;lt;Device&amp;gt;;<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Devic=
e mergeDeviceInfo(const Device &amp; _first, const Device &amp; _second) {<=
br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Implementation<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=
=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device=
List deviceList;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some work<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto foundDeviceIter0 =3D std::find_if(deviceLi=
st.begin(), deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 ... // Some first creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<=
br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto foundDeviceIter1 =3D std::find_if(de=
viceList.begin(), deviceList.end(), [=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 ... // Some second creteria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (deviceList.end() !=3D foundDe=
viceIter0 &amp;&amp; deviceList.end() !=3D foundDeviceIter1) {<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device mergedDevice =3D De=
viceManager::mergeDeviceInfo(*foundDeviceIter0, *foundDeviceIter1);<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some other work<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }</div><div><br></div><div>As=
 you can see in case one helper function it is easy to manipulate and use i=
t, but in case of a lot of functions it would be better to support some kin=
d of extension methods:</div><div><br></div><div>namespace DeviceManager {<=
br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class Device {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 ... // Other member functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t getId() const {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return id_;<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 private:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 ... // Other member variables<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint32_t id_;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 };<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using DeviceList =3D std::vector&=
amp;lt;Device&amp;gt;;<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 1. If it is=
 called by reference type prefer this overload function<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 Device mergeDeviceInfo(const Device &amp; _first, const Dev=
ice &amp; _second) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // I=
mplementation<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 // 2. If it is called by pointer type prefer this overload functi=
on<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Device mergeDeviceInfo(const Device * =
_firstPtr, const Device * _secondPtr) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 ... // Implementation<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=
=C2=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 DeviceManager::DeviceList deviceList;<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 ... // Some work<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto fou=
ndDeviceIter0 =3D std::find_if(deviceList.begin(), deviceList.end(), [=3D] =
{<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some first creteria<=
br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 aut=
o foundDeviceIter1 =3D std::find_if(deviceList.begin(), deviceList.end(), [=
=3D] {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some second cre=
teria<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 });<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 if (deviceList.end() !=3D foundDeviceIter0 &amp;&amp; deviceList.end() =
!=3D foundDeviceIter1) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 1=
.. Overload function for references if called<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 // ADL will search in dependent scopes also for calling fun=
ctions by object reference<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 De=
viceManager::Device &amp; firstFoundDevice =3D *foundDeviceIter0;<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 DeviceManager::Device &amp; secondFoun=
dDevice =3D *foundDeviceIter1;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 DeviceManager::Device mergedDevice =3D firstFoundDevice.mergeDeviceInfo=
(secondFoundDevice);<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // 2=
.. Overload function for pointers if called<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 // ADL will search in dependent scopes lso for calling func=
tions by object pointer<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Devic=
eManager::Device mergedDevice =3D foundDeviceIter0-&gt;mergeDeviceInfo(*fou=
ndDeviceIter1);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Some o=
ther work<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 }</div>=
<div><br></div><div><b>Propousal for extension of ADL on template parameter=
..</b> Lets consider the following example:</div><div><br></div><div>=C2=A0=
=C2=A0=C2=A0 namespace IPCBus {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 class ICl=
ient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Other member functions=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 template &amp;lt=
;typename TClient&amp;gt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 static std::shared_ptr&amp;lt;IClient&amp;gt; buildClient() {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto cli=
ent =3D std::shared_ptr(new TClient);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // IMPORTANT THINGS AFTER INITIALIZAT=
ION. CANNOT BE SKIPED !!<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 return client;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 prote=
cted:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Client() =
=3D default;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br>=C2=A0=C2=A0=C2=A0 }=
=C2=A0 // namespace IPCBus<br><br>=C2=A0=C2=A0=C2=A0 class RealClient : pub=
lic IClient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 RealClient()<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 : IClient() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=
=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=C2=A0 using namespace std;<br><br>=
=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto real=
Client =3D make_shared&amp;lt;RealClient&amp;gt;();<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 // WE MISSED THE VERY IMPORTANT STEPS IN CREATION OF OBJECT !!=
<br></div></div></blockquote><div><br></div><div>If you don&#39;t want Real=
Client instances to be created by calling the default constructor, the defa=
ult constructor should not be public. There are other techniques you can us=
e to allow IClient to create instances of RealClient without exposing a pub=
lic default constructor that creates a broken object. Your approach doesn&#=
39;t stop someone from doing this:</div><div><br></div><div>=C2=A0 make_uni=
que&lt;RealClient&gt;() // still broken</div><div><br></div><div>or this:</=
div><div><br></div><div>=C2=A0 std::make_shared&lt;RealClient&gt;() // stil=
l broken</div><div><br></div><div>It&#39;s also broken by the intent of P05=
51R3 (adopted for C++20), which intends to make it possible to implement st=
andard library functions as function objects instead of as real functions, =
and by P0921R2, which says that you can&#39;t rely on (for instance) how a =
standard-library function will partially order with respect to a function o=
f your own.</div><div><br></div><div>So I don&#39;t think this approach rea=
lly solves the problem you&#39;re trying to address, especially not when us=
ed to subvert calls to standard library functions.</div><div><br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>=C2=A0=
=C2=A0=C2=A0 }</div><div><br></div><div>As you can see in case one helper f=
unction it is easy to manipulate and use it, but in case of a lot of functi=
ons it would be better to support some kind of extension methods:</div><div=
><br></div><div>=C2=A0=C2=A0=C2=A0 namespace IPCBus {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 class IClient {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // Ot=
her member functions<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 template &amp;lt;typename TClient&amp;gt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static std::shared_ptr&amp;lt;IClient&amp;gt=
; buildClient() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 auto client =3D std::shared_ptr(new TClient);<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ... // IMPORTANT THI=
NGS AFTER INITIALIZATION. CANNOT BE SKIPED !!<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return client;<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 protected:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 Client() =3D default;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br><br=
>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 template &amp;lt;typename T, typename ... T=
Args&amp;gt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 std::shared_ptr&amp;lt;T&amp=
;gt; make_shared(TArgs&amp;&amp;... _args) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 return IClient::buildClient(std::forward&amp;lt;TArgs&amp;g=
t;(_args)...);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br></div></div></blockqu=
ote><div><br></div><div>This, if in scope, would likely be ambiguous with s=
td::make_shared. And if you make it a better overload candidate, it would h=
ijack all make_shared calls that should invoke std::make_shared. Adding an =
overload to someone else&#39;s overload set, when they didn&#39;t design fo=
r their overload set to be extensible, is a very bad design practice.</div>=
<div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=
=3D"ltr"><div>=C2=A0=C2=A0=C2=A0 }=C2=A0 // namespace IPCBus<br><br>=C2=A0=
=C2=A0=C2=A0 class RealClient : public IClient {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 RealClient()<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 : IClient() {<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 };<br><br>=C2=A0=C2=A0=
=C2=A0 using namespace std;<br><br>=C2=A0=C2=A0=C2=A0 int main() {<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto realClient =3D make_shared&amp;lt;RealClie=
nt&amp;gt;();<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // We use our own version o=
f make_shared that is delegate creation of object to builder method<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 // Cool !!<br>=C2=A0=C2=A0=C2=A0 }</div><div><b=
r></div><div>As <b>Herb Sutter</b> said at <b>CppCon 2017: Herb Sutter =E2=
=80=9CMeta: Thoughts on generative C++=E2=80=9D</b>:<br>&quot;Abstraction a=
re hiders by definition. If they did not do this they are useless ...&quot;=
<br>&quot;It&#39;s not the problem. It is the point.&quot;<br><br>I see thi=
s suggestion to extend <b>ADL</b> search on caller object and on template p=
arameter as simplifier for Library Writters and also General Programmers</d=
iv></div></blockquote><div><br></div><div>I don&#39;t agree at all with you=
r motivation, but nonetheless I do agree with your conclusion: it does seem=
 reasonable for ADL to consider associated classes and namespaces of templa=
te arguments in the case where the function name is a template-id. I suspec=
t this was not done previously because the callee in a function call for wh=
ich ADL is performed was very rarely a template-id prior to P0846R0, but no=
w we&#39;ve adopted that paper for C++20, it would make sense to take the a=
ssociated classes and namespaces of the template arguments into account, an=
d especially because we now allow objects of class type as non-type templat=
e arguments:</div><div><br></div><div>namespace N {</div><div>=C2=A0 struct=
 Params { /*...*/ };</div><div>=C2=A0 auto make_dynamic(Params P) { /*...*/=
 }<br></div><div>=C2=A0 template&lt;Params P&gt; auto make_static() { /*...=
*/ }</div><div>}<br></div><div>auto x =3D make_dynamic(N::Params{1, 2, 3});=
 // OK</div><div>auto y =3D make_static&lt;N::Params{1, 2, 3}&gt;(); // err=
or today, could be valid tomorrow</div></div></div></div></div>
</blockquote></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9579b759-d5c0-41c9-a224-5c54fcf88274%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9579b759-d5c0-=
41c9-a224-5c54fcf88274%40isocpp.org</a>.<br>
</blockquote></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQqmM44LZXC28U4A%3Dn2PV9TJCDYPf9N=
RaUaYX4XGEXDv0Tg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqmM44LZXC=
28U4A%3Dn2PV9TJCDYPf9NRaUaYX4XGEXDv0Tg%40mail.gmail.com</a>.<br />

--0000000000007a18230577e5dc24--

.