Date: Wed, 31 Jul 2024 03:34:39 +0400
Hi Nadir,you are pushing function pointers to a vector.CorrectHow should the compiler keep track, at which position which function pointer was pushed?A key concept to keep in mind,A function pointer is compile time entity.That means that all the instantiated functions in your program are well defined, and tracked by the compiler, and tied to their bodies at link time. You are talking about an internal compiler structure.The only way to push a function pointer into a container is by naming it through pointer aliasing.There is no function body created on the fly.(Yes...yes... there is a technique called self extracting code, but that's not our concern here)All function pointer objects created in your program are references to functions you defined explicitly or the compiler instantiated implicitly.You cannot writeusing U = void(int);U* f = new U; // compiler errorBut at compile time it is not even known, if, how many and which pointers are pushed into the vector. So how should the compiler fill such a structure?Same remarks,The case of function pointers, as well as the other 3 categories i named previously, you can only store references to well defined function objects.U* f = &someFoo; // defined by user/compilervec.push_back(f);vec[0](123); // calls someFoo(123)Which means:\-/ elem in vec, -] ! Foo in program : where elem = referenceTo(Foo).The body of Foo is well defined. All templates arguments replaced, all false constexp expressions branchs striked out.Thus you don't need to keep track of any order.And element of vec points to a function; that function pointer is stored in a table in compiler, and its signature is fully explicit.i.e all templates arguments resovled. vec. compiler inner hash table | elem0. ------> | someFoo | elem1. ------> | templatedFoo<double> | elem2 _____/It is a biiiig family of shared pointers, system wide.Overload resolution can be directly done at compile time. As the type is directly known.Exactly. -----Ursprüngliche Nachricht-----Von: organicoman <organicoman_at_[hidden]>Gesendet: Di 30.07.2024 23:44Betreff: Re: [std-proposals] Function overload set type information lossAn: Sebastian Wittmeier via Std-Proposals <std-proposals_at_[hidden]>; CC: Sebastian Wittmeier <wittmeier_at_[hidden]>; body { font-family: monospace; } Hi Sebastian,Recall that we have two type of information.The apparent typeThe effective type. The is applied only for the foloowing type categories-Arrays-Function templates -Variable template The apparent type , is the one we are using currently.Example:template<typename T>void foo(int);decltype(foo<char>); // void(*)(int) no matter what T is But the effective type: effective_decltype(foo<char>); // void(*)<char>(int), and it depends on the template argument Observe that the last is tagged with the template argument value, and the 1st is not. To store object of type foo above, we have two optionsEither you write:std::vector<effective_decltype(foo)> myVec;orstd::vector<void(*)(int)> myVec;It is exactly the same buffer size and alignment.The only difference is that, for the 1st option, the compiler keeps and internal structure filled with the effective type of the object pushed into the vector, and tracks where that information is needed, replace it there, then trashs everything at the end. The same when it does overload resolution. Actually it is the same implementation.It is all compile time process.No runtime is affected.Sent from my Galaxy -------- Original message --------From: Sebastian Wittmeier via Std-Proposals <std-proposals_at_[hidden]>Date: 7/31/24 12:49 AM (GMT+04:00)To: Std-Proposals <std-proposals_at_[hidden]>Cc: Sebastian Wittmeier <wittmeier_at_[hidden]>Subject: Re: [std-proposals] Function overload set type information loss Hi organicoman, that is the whole point. You want a compile time feature, where the compiler keeps the information, how an object is created.But then on the other hand, you want to store those objects into a container. E.g. std::array<int32_t, N> Where should this additional meta information be kept?The storing of values into the container is in the general case done at runtime.It could be dependent on user or file inputs.So the compiler (compile-time) cannot follow it any longer. The array itself has a fixed size of 4*N bytes, just enough for the int.So we also cannot store type ids at runtime together with the ints themselves. We loose the meta / extended type information. It is not a language shortcoming, but there is no logical way to solve this for containers.You have to give up one of your requirements: Either - the container stores additional information (std::any like) - all entries in the container will have the same meta type instead of an individual one - it only works for containers clearly initialized in a way, which can be deduced at compile-time, e.g.std::array<int32_t, 5> myarray{1, 2, 3, 4, 5}; - it won't work with containers at all - it only works for containers modified in consteval/constinit code (which the compiler may choose to run at compile-time) Best,Sebastian -----Ursprüngliche Nachricht-----Von: organicoman <organicoman_at_[hidden]>Gesendet: Di 30.07.2024 22:01Betreff: Re: [std-proposals] Function overload set type information lossAn: Sebastian Wittmeier via Std-Proposals <std-proposals_at_[hidden]>; CC: Sebastian Wittmeier <wittmeier_at_[hidden]>; .bodyclass { font-family: monospace; } As far as the constructor of A above is concerned, it accepts argumentof apparent type int, but as soon as we pass arguments with a signature like the globalVar above it will capture an effective type of this form (int)<T> The type alias meta_int above, is just an intwith some extra meta datawhen needed.With AutoWrapper class in your example, You have to be intrusive, and any data member of AutoWrapper type, imposes at any class tobe templated. Thus that class cannot be used as a container template parameter.
Received on 2024-07-30 23:34:52